当前位置 : 主页 > 手机开发 > harmonyos >

IOCP网络模型基本步骤

来源:互联网 收集:自由互联 发布时间:2023-10-08
一、定义结构 typedef struct PER_HANDLE_DATA { SOCKET s; SOCKADDR_IN RemoteAddr; }*PPER_HANDLE_DATA; typedef struct PER_IO_DATA { WSAOVERLAPPED ol; char buf[12]; #define OP_READ 1 #define OP_WRITE 2 int nOperation; }*PPER_IO_DATA; 二、


 

一、定义结构

typedef struct PER_HANDLE_DATA 
   {
      SOCKET s;
      SOCKADDR_IN RemoteAddr; 
   }*PPER_HANDLE_DATA;
   typedef struct PER_IO_DATA
   {
     WSAOVERLAPPED ol;
     char buf[12];
     #define OP_READ  1
     #define OP_WRITE 2
     int nOperation;
    }*PPER_IO_DATA;

 

二、创建一个完成端口

HANDLE hCompletion=CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);

三、创建合适的工作线程

SYSTEM_INFO si;
   GetSystemInfo(&si);
   for(int i=0;i<si.dwNumberOfProcessors*2;++i)//如果需要使用WaitForSingleObject之类使线程等待,避免CPU空闲
   CreateThread(NULL,0,WorkThread,(LPVOID)hCompletion,0,0);

四、绑定监听socket

SOCKET sListen=socket(AF_INET,SOCK_STREAM,0);
   SOCKADDR_IN srvaddr;
   srvaddr.sin_addr.S_un.S_addr=INADDR_ANY;
   srvaddr.sin_family=AF_INET;
   srvaddr.sin_port=htons(4567);
   bind(s,(SOCKADRR*)&srvaddr,sizeof srvaddr);
   listen(s,5);

五、处理客户连接

while(1)
   {
      SOCKADDR_IN Remoteaddr;
      int nlen=sizeof Remoteaddr; 
      SOCKET sAccept=accept(sListen,(SOCKADDR*)Remoteaddr,&nlen);
      PPER_HANDLE_DATA pPerHandle=(PER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA));
      pPerHandle->s=sAccept;
      memcpy(&pPerHandle->RemoteAddr,Remoteaddr,nlen);
 
      CreateIoCompletionPort((HANDLE)pPerHandle->s,hCompletion,(DWORD)perHandle,0);//关联per数据
      PPER_IO_DATA pPerIO=(PER_IO_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_DATA));
      pPerIO->nOperation=OP_READ;
      WSABUF buf;
      buf.buf=pPerIO->buf;
      buf.len=12;
      DWORD dwRecv;
      DWORD dwFlags=0;
      WSARecv(pPerHandle->s,&buf,1,&dwRecv,&dwFlags,&pPerIO->ol,NULL);//投递第一个请求
   }
六、处理客户请求(工作线程)
   HANDLE hCompletion=(HANDLE)lpParam;
   DWORD dwTrans;
   PPER_HANDLE_DATA pPerHandle;
   PPER_IO_DATA pPerIO;
 
   while(1)
   {
     bool ok=GetQueuedCompletionStatus(hCompletion,&dwTrans,(PULONG_PTR)&pPerHandle,(LPOVERLAPPED*)&pPerIO,WSA_INFINITE);//查看是否有异步IO请求完成 完成返回
     if(!bok)//出错了
     {
       closesocket(pPerHandle->s);
       GlobalFree(pPerHandle);
       GlobalFree(pPerIO);
       continue;
     }
     if(dwTrans==0&&(pPerIO->nOperation==OP_READ||pPerIO->nOperation==OP_WRITE))//连接关闭了
     {
      closesocket(pPerHandle->s);
      GlobalFree(pPerHandle);
      GlobalFree(pPerIO);
      continue; 
     }
     switch(pPerIO->nOperation)
     {
       case OP_READ:
         pPerIO->buf[dwTrans]='/0';
         printf(pPerIO->buf);
         WSABUF buf;
         buf.buf=pPerIO->buf;
         buf.len=12;
         pPerIO->nOperation=OP_READ;
         DWORD nFlags=0;
         WSARecv(pPerHandle->s,&buf,1,&dwTrans,&nFlags,&pPerIO->ol,NULL);//继续投递
         break;
      case OP_WRITE:
      case OP_ACCEPT:
         break;
     }
   
   }
上一篇:MCI(媒体控制接口)相关知识
下一篇:没有了
网友评论