亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? iocp.cpp

?? 基于完成端口的TCP網絡通信框架實現 工程iocp中包含了框架實現的所有代碼
?? CPP
字號:
#include <process.h>
#include <set>
#include <string>
#include "iocp.h"

using std::set;
using std::pair;
using std::string;

#pragma comment(lib,"wsock32")
#pragma comment(lib,"Ws2_32")

/***************************************
              NetIOCPBase
***************************************/

//worker接收到的操作
enum NET_OPTYPE
{
  NOT_SOCKNEW,   //新socket
  NOT_SOCKCLOSE, //關閉socket
  NOT_DATASEND,  //發送數據
  NOT_DATARECV,  //接收數據
  NOT_SHUTDOWN,  //關閉server
};

int NetIOCPBase::ref=0;

static void stopTCP(SOCKET s)
{
	//int b;
	//char buf[256];

  shutdown(s, SD_SEND);
	//while ((b = recv(s, buf, 256, 0))!=0)
  //{	
  //  if (b==SOCKET_ERROR)
	//		break;
  //}
	closesocket(s);
}

void NetIOCPBase::senddata(SOCKET s,PerIoData *iodata)
{
  assert(iodata->len<=NET_BLOCK_SIZE&&iodata->len>0);
  iodata->sock=s;
  map<SOCKET,Channel *>::iterator iter;
  mmsend_pool_mutex.Lock();
  iter=mmsend_pool.find(s);
  if(mmsend_pool.end()==iter)
  {
    mmsend_pool_mutex.Unlock();
    delete iodata;
    return;
  }
  Channel *chan=iter->second;
  chan->sendqueue.push_back(iodata);
  if(chan->busy)
  {
    mmsend_pool_mutex.Unlock();
    return;
  }
  iodata=chan->sendqueue.front();
  chan->sendqueue.pop_front();
  chan->busy=true;
  mmsend_pool_mutex.Unlock();
  aio_send(iodata->sock,iodata);
}

void NetIOCPBase::wkshutdown()
{
  set<SOCKET> clients;
  {
    map<SOCKET,Channel *>::iterator iter;
    Locker lock(&mmsend_pool_mutex);
    for_each_iter(mmsend_pool,iter)
    {
      Channel *chan=iter->second;
      list<PerIoData *>::iterator dataiter;
      for_each_iter(chan->sendqueue,dataiter)
      {
        delete *dataiter;
      }
      clients.insert(chan->sock);
      delete chan;
    }
    mmsend_pool.clear();
  }
  set<SOCKET>::iterator iter;
  for_each_iter(clients,iter)
  {
    close(*iter);
  }
  for(int i=0;i<(int)mwthread.size();++i)
  {
    PerIoData *iodata=new PerIoData;
    memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
    iodata->sock=INVALID_SOCKET;
    iodata->op_type=NOT_SHUTDOWN;
    BOOL ok=PostQueuedCompletionStatus(miocp,1,iodata->sock,(LPOVERLAPPED)iodata);
    assert(ok);
  }
  for(int i=0;i<(int)mwthread.size();++i)
  {
    WaitForSingleObject(mwthread[i], INFINITE);
    CloseHandle(mwthread[i]);
  }
}

void NetIOCPBase::runloop()
{
  recv_allnetevents();
  NetEvent ne;
  while(peek_netevent(&ne))
  {
    switch(ne.event)
    {
    case NE_SOCKNEW:
      net_open_handler(ne.iodata->sock);
      aio_recv(ne.iodata->sock,ne.iodata);
      break;
    case NE_SOCKCLOSED:
      net_closed_handler(ne.iodata->sock);
      delete ne.iodata;
      break;
    case NE_DATARECVED:
      net_data_handler(ne.iodata);
      delete ne.iodata;
      break;
    default:
      assert(0);
      delete ne.iodata;
      break;
    }
  }
}



bool NetIOCPBase::delete_sendqueue(SOCKET s)
{
  Channel *chan=NULL;
  {
    map<SOCKET,Channel *>::iterator iter;
    Locker lock(&mmsend_pool_mutex);
    iter=mmsend_pool.find(s);
    if(iter!=mmsend_pool.end())
    {
      chan=iter->second;
      mmsend_pool.erase(iter);
    }
  }
  if(chan!=NULL)
  {
    list<PerIoData *>::iterator iter;
    for_each_iter(chan->sendqueue,iter)
    {
      delete *iter;
    }
    delete chan;
  }
  return chan!=NULL;
}

bool NetIOCPBase::create_sendqueue(SOCKET s)
{
  typedef map<SOCKET,Channel *>::iterator ChanMapIter;
  pair<ChanMapIter,bool> ret;
  Channel *chan=new Channel;
  chan->sock=s;
  chan->busy=false;
  {
    Locker lock(&mmsend_pool_mutex);
    ret=mmsend_pool.insert(make_pair(chan->sock,chan));
  }
  if(!ret.second)
  {
    delete chan;
  }
  return ret.second;
}

void NetIOCPBase::worker_func()
{
  SOCKET sock;
  PerIoData *iodata;
  DWORD bytes;
  bool running=true;
  while (running)
  {
    bytes=0;
    BOOL ret = GetQueuedCompletionStatus(miocp, &bytes, (LPDWORD) & sock,
                                         (LPOVERLAPPED *) & iodata, INFINITE);
    if((!ret&&iodata!=NULL) || bytes==0)
    {
      assert(iodata->sock==sock);
      if(delete_sendqueue(iodata->sock))
      {
        stopTCP(iodata->sock);
        NetEvent ne;
        ne.event=NE_SOCKCLOSED;
        ne.iodata=iodata;
        post_netevent(ne);
      }
      else
      {
        delete iodata;
      }
      continue;
    }
    assert(iodata!=NULL);
    assert(iodata->sock==sock);
    switch(iodata->op_type)
    {
    case NOT_SOCKNEW:
      {
        bool ok=create_sendqueue(iodata->sock);
        assert(ok);
        NetEvent ne;
        ne.event=NE_SOCKNEW;
        ne.iodata=iodata;
        post_netevent(ne);
      }
      break;
    case NOT_SOCKCLOSE:
      {
        stopTCP(iodata->sock);
        NetEvent ne;
        ne.event=NE_SOCKCLOSED;
        ne.iodata=iodata;
        post_netevent(ne);
      }
      break;
    case NOT_DATASEND:
      {
        if(bytes<iodata->databuf.len)
        {
          aio_resend(iodata,bytes);
          break;
        }
        SOCKET s=iodata->sock;
        delete iodata;
        map<SOCKET,Channel *>::iterator iter;
        {
          Locker lock(&mmsend_pool_mutex);
          iter=mmsend_pool.find(s);
          if(iter==mmsend_pool.end())
            break;
          Channel *chan=iter->second;
          if(chan->sendqueue.empty())
          {  
            chan->busy=false;
            break;
          }
          iodata=chan->sendqueue.front();
          chan->sendqueue.pop_front();
        }
        aio_send(iodata->sock,iodata);
      }
      break;
    case NOT_DATARECV:
      {
        NetEvent ne;
        ne.event=NE_DATARECVED;
        ne.iodata=iodata;
        SOCKET s=iodata->sock;
        iodata->len=bytes;
        post_netevent(ne);
        iodata=new PerIoData;
        aio_recv(s,iodata);
      }
      break;
    case NOT_SHUTDOWN:
      {
        running=false;
        delete iodata;
      }
      break;
    default:
      assert(0);
      break;
    }
  }
}

void NetIOCPBase::aio_send(SOCKET s,PerIoData *iodata)
{
  memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
  iodata->sock=s;
  iodata->op_type=NOT_DATASEND;
  iodata->databuf.buf=iodata->data;
  iodata->databuf.len=iodata->len;
  DWORD bytes = 0;
  DWORD flags = 0;
  int ret = WSASend(iodata->sock, &iodata->databuf, 1, &bytes, flags,
                    (LPWSAOVERLAPPED)iodata, NULL);
  //發送失敗,通知關閉連接
  if (ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
  {
    BOOL ok=PostQueuedCompletionStatus(miocp, 0, iodata->sock, (LPOVERLAPPED)iodata);
    assert(ok);
  }
}

void NetIOCPBase::aio_recv(SOCKET s,PerIoData *iodata)
{
  memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
  iodata->sock=s;
  iodata->op_type=NOT_DATARECV;
  iodata->databuf.buf=iodata->data;
  iodata->databuf.len=sizeof(iodata->data);
  DWORD bytes = 0;
  DWORD flags = 0;
  int ret = WSARecv(iodata->sock, &iodata->databuf, 1, &bytes, &flags,
                    (LPWSAOVERLAPPED)iodata, NULL);
  if (ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
  {
    BOOL ok=PostQueuedCompletionStatus(miocp, 0, iodata->sock, (LPOVERLAPPED)iodata);
    assert(ok);
  }
}

void NetIOCPBase::aio_resend(PerIoData *iodata,int lastlen)
{
  assert(lastlen<(int)iodata->databuf.len);
  iodata->databuf.buf+=lastlen;
  iodata->databuf.len-=lastlen;
  DWORD bytes = 0;
  DWORD flags = 0;
  int ret = WSASend(iodata->sock, &iodata->databuf, 1, &bytes, flags,
                    (LPWSAOVERLAPPED)iodata, NULL);
  //發送失敗,通知關閉連接
  if (ret == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
  {
    BOOL ok=PostQueuedCompletionStatus(miocp, 0, iodata->sock, (LPOVERLAPPED)iodata);
    assert(ok);
  }
}

void NetIOCPBase::close(SOCKET s)
{
  if(delete_sendqueue(s))
  {
    PerIoData *iodata=new PerIoData;
    memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
    iodata->sock=s;
    iodata->op_type=NOT_SOCKCLOSE;
    BOOL ok=PostQueuedCompletionStatus(miocp, 1, iodata->sock, (LPOVERLAPPED)iodata);
    assert(ok);
  }
}

NetIOCPBase::NetIOCPBase()
{
  if(ref==0)
  {
    WSADATA data;
    if (WSAStartup(0x0202, &data) != 0)
    {
      throw string("WSAStartup fail!");
    }
  }
  started=false;
  miocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
  if (NULL == miocp)
    throw string("CreateIoCompletionPort fail!");
  ++ref;
}
NetIOCPBase::~NetIOCPBase()
{
  if(started)
  {  
    stop();
    started=false;
  }
  if(miocp!=NULL)
  {  
    CloseHandle(miocp);
    miocp=NULL;
  }
  if(ref==1)
  {
    WSACleanup();
  }
  --ref;
}
void NetIOCPBase::start()
{
  if(!started)
  {
    SYSTEM_INFO sys_info;
    GetSystemInfo(&sys_info);
    for (int i = 0;i < (int)sys_info.dwNumberOfProcessors*2;++i)
    {
      HANDLE thread = (HANDLE)_beginthreadex(NULL, 0, completion_port_worker_thread, this, 0, NULL);
      if (NULL == thread)
        throw string("_beginthreadex,completion_port_worker_thread,fail!");
      mwthread.push_back(thread);
    }
    start_run();
    started=true;
  }
}
void NetIOCPBase::stop()
{
  if(started)
  {
    stop_run();
    wkshutdown();
    started=false;
  }
}

unsigned int __stdcall NetIOCPBase::completion_port_worker_thread(void *cookie)
{
  ((NetIOCPBase *)cookie)->worker_func();
  _endthreadex(0);
  return 0;
}

/***************************************
              NetIOCPServer
***************************************/
void NetIOCPServer::accept_func()
{
  while(1)
  {
    SOCKET client = accept(mserver, NULL, NULL);
    if (client == INVALID_SOCKET)
    {
      //如果服務器套接字已經關閉,退出線程
      int ret = WSAGetLastError();
      if (ret == WSAEINTR   ||
          ret == WSAENOTSOCK||
          ret == WSANOTINITIALISED)
      {
        break;
      }
      assert(0);
      continue;
    }
    HANDLE port = CreateIoCompletionPort((HANDLE)client, miocp, (DWORD)client, 0);
    //如果不能將套接字關聯到完成端口
    if (port == NULL)
    {
      stopTCP(client);
      continue;
    }
    PerIoData *iodata=new PerIoData;
    memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
    iodata->sock=client;
    iodata->op_type=NOT_SOCKNEW;
    BOOL ok=PostQueuedCompletionStatus(miocp,1,iodata->sock,(LPOVERLAPPED)iodata);
    assert(ok);
  }
}

NetIOCPServer::NetIOCPServer(unsigned short port)
{
  mport=port;
  mserver= WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
  if (mserver == INVALID_SOCKET)
    throw string("WSASocket fail!");
  sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  addr.sin_port = htons(mport);
  if (bind(mserver, (sockaddr *)&addr, sizeof(addr)) != 0)
    throw string("bind fail!");
  if (listen(mserver, SOMAXCONN) != 0)
    throw string("listen fail!");
  mathread=NULL;
}

NetIOCPServer::~NetIOCPServer()
{
  stop_run();
}

void NetIOCPServer::start_run()
{
  mathread=(HANDLE)_beginthreadex(NULL, 0, completion_port_accept_thread, this, 0, NULL);
  if(mathread==NULL)
    throw string("_beginthreadex,completion_port_accept_thread,fail!");
}
void NetIOCPServer::stop_run()
{
  if(mserver!=INVALID_SOCKET)
  {
    closesocket(mserver);
    mserver=INVALID_SOCKET;
    if(mathread!=NULL)
    {
      WaitForSingleObject(mathread,INFINITE);
      CloseHandle(mathread);
      mathread=NULL;
    }
  }
}
unsigned int __stdcall NetIOCPServer::completion_port_accept_thread(void *cookie)
{
  ((NetIOCPServer *)cookie)->accept_func();
  _endthreadex(0);
  return 0;
}

/***************************************
              NetIOCPClient
***************************************/
//
// 注意: connect 成功后
// 參數SOCKET返回連接的socket,此時底層尚未完成對該socket的資源分配
// iocp完成資源分配后會在net_open_handler里面將該socket返回
//
bool NetIOCPClient::connect(const char *dotip,unsigned short port,SOCKET *ss)
{
  SOCKET s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
  if (s == INVALID_SOCKET)
  {
    return false;
  }

  sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_addr(dotip);
  addr.sin_port = htons(port);
  if (::connect(s, (sockaddr *)&addr, sizeof(addr)) != 0)
  {
    closesocket(s);
    return false;
  }

  HANDLE hdl = CreateIoCompletionPort((HANDLE)s, miocp, (DWORD)s, 0);
  if (hdl == NULL)
  {
    stopTCP(s);
    return false;
  }
  PerIoData *iodata=new PerIoData;
  memset(&iodata->overlapped,0,sizeof(OVERLAPPED));
  iodata->sock=s;
  iodata->op_type=NOT_SOCKNEW;
  BOOL ok=PostQueuedCompletionStatus(miocp, 1, iodata->sock, (LPOVERLAPPED)iodata);
  assert(ok);
  if(ss)
    *ss=s;
  return true;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产日韩欧美精品在线| 国产一区二区精品久久99| 日韩伦理av电影| 国产精品福利电影一区二区三区四区 | 一区二区三区电影在线播| 国产精品久久久99| 亚洲视频在线一区二区| 亚洲欧洲日韩综合一区二区| 一区在线中文字幕| 亚洲美女在线国产| 亚洲精品免费在线播放| 一区二区三区中文字幕| 亚洲一区二区欧美激情| 午夜精品在线视频一区| 日韩专区欧美专区| 久久国产乱子精品免费女| 精东粉嫩av免费一区二区三区| 激情综合亚洲精品| 成人夜色视频网站在线观看| 成a人片亚洲日本久久| 91丨九色丨国产丨porny| 欧美视频一区二区三区在线观看| 欧美三级日韩三级| 日韩欧美电影在线| 久久久亚洲高清| 国产精品水嫩水嫩| 亚洲精品日韩一| 日本三级亚洲精品| 国产老妇另类xxxxx| 不卡av在线网| 欧美人妖巨大在线| 久久一区二区三区四区| 国产精品人妖ts系列视频| 樱花草国产18久久久久| 日韩精品电影一区亚洲| 国产精品香蕉一区二区三区| 97se亚洲国产综合自在线不卡| 欧美丝袜丝交足nylons| 精品捆绑美女sm三区| 国产女人18毛片水真多成人如厕| 亚洲美女电影在线| 日本特黄久久久高潮| 成人中文字幕在线| 欧美性videosxxxxx| 精品黑人一区二区三区久久 | 亚洲欧美日韩国产综合| 日韩专区一卡二卡| 成人av片在线观看| 欧美久久久久免费| 国产精品久久99| 日本免费在线视频不卡一不卡二| 国产高清精品网站| 欧美人牲a欧美精品| 国产欧美日本一区视频| 视频在线观看一区二区三区| 国产91露脸合集magnet| 欧美日韩精品一区二区三区四区 | 中国av一区二区三区| 爽好多水快深点欧美视频| 成人综合在线观看| 欧美一级欧美三级| 亚洲欧美日韩一区二区三区在线观看 | 亚洲成人av福利| 丁香婷婷深情五月亚洲| 欧美精品123区| 日韩一区在线播放| 激情久久久久久久久久久久久久久久| 91在线观看一区二区| 日韩欧美成人一区| 一区二区三区在线高清| 丰满少妇久久久久久久| 日韩一区二区三区电影在线观看| 亚洲欧美日韩在线| 国产成人日日夜夜| 欧美一区二区三区成人| 一区2区3区在线看| 成人h动漫精品一区二| 精品久久久久一区| 日韩电影在线看| 在线亚洲一区二区| 国产精品三级av| 国内外成人在线视频| 欧美福利视频导航| 一区2区3区在线看| 91美女视频网站| 中文字幕精品一区| 国产九色精品成人porny| 欧美一级片在线看| 日本不卡免费在线视频| 精品视频在线免费| 亚洲一区免费视频| 色婷婷久久综合| 亚洲少妇30p| www.久久精品| 亚洲欧洲性图库| www.在线欧美| 国产精品久久久久久久久动漫| 国产伦精品一区二区三区在线观看| 欧美一区三区二区| 亚洲成人免费电影| 欧美日韩黄色影视| 午夜精品福利久久久| 欧美日韩一区三区| 视频一区欧美精品| 91精品国产综合久久精品麻豆| 午夜精品福利一区二区三区蜜桃| 欧美日韩不卡一区| 日精品一区二区| 欧美一区二区在线观看| 免费日本视频一区| 日韩视频中午一区| 韩国av一区二区三区| 久久久久国色av免费看影院| 粉嫩嫩av羞羞动漫久久久| 国产精品久久精品日日| 色综合久久99| 亚洲成人黄色小说| 日韩无一区二区| 国产成人免费xxxxxxxx| 中文字幕一区二区三区不卡| 色综合天天综合网天天狠天天| 亚洲一区在线观看视频| 91精品国产欧美一区二区| 久久国内精品自在自线400部| 2023国产精品| av资源站一区| 亚洲一区二区欧美日韩| 日韩一级视频免费观看在线| 国产一区视频导航| 国产精品久久久久国产精品日日| 色天使色偷偷av一区二区| 亚洲国产精品久久艾草纯爱| 欧美一区二区在线免费观看| 国产精品一区久久久久| 亚洲男人的天堂在线观看| 欧美日韩一区二区三区高清| 久久精品国产99国产精品| 欧美韩国日本综合| 欧美影院一区二区| 精品一区二区三区免费| 中文字幕永久在线不卡| 欧美卡1卡2卡| 国产sm精品调教视频网站| 亚洲精品视频在线| 精品久久久久久久久久久院品网 | 欧美日韩中文另类| 国内外精品视频| 亚洲一区中文日韩| 久久久久99精品一区| 在线观看国产日韩| 国模大尺度一区二区三区| 亚洲区小说区图片区qvod| 欧美一级黄色片| 91亚洲精品一区二区乱码| 免费欧美日韩国产三级电影| 亚洲欧洲一区二区在线播放| 欧美一个色资源| 色综合久久天天| 国产麻豆精品视频| 亚洲va在线va天堂| 国产午夜亚洲精品不卡| 91精品国产91久久综合桃花| 9久草视频在线视频精品| 麻豆精品在线看| 一区二区三区在线免费播放| 久久久久久久久久久久电影| 欧美日韩在线观看一区二区| 国产成人午夜精品影院观看视频 | 石原莉奈在线亚洲三区| 日韩亚洲国产中文字幕欧美| 不卡免费追剧大全电视剧网站| 五月婷婷激情综合| 椎名由奈av一区二区三区| 精品国产成人系列| 欧美日韩一区在线| 成人av资源下载| 国产一区在线观看麻豆| 日韩电影免费在线| 亚洲免费观看在线视频| 国产女人aaa级久久久级| 欧美一卡二卡三卡| 欧美伊人精品成人久久综合97| 成人午夜视频福利| 国产综合色视频| 青青青伊人色综合久久| 亚洲一区二区av电影| 国产精品成人免费在线| 国产欧美一区二区三区在线老狼| 日韩精品一区二| 91精品国产麻豆| 欧美嫩在线观看| 欧美日韩免费高清一区色橹橹| 91无套直看片红桃| 波多野结衣视频一区| 国产精品18久久久久久久久| 韩国一区二区三区| 久久不见久久见免费视频7| 日本特黄久久久高潮| 日韩av在线播放中文字幕| 视频一区二区三区在线|