博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOCP网络模型基本步骤
阅读量:4106 次
发布时间:2019-05-25

本文共 2197 字,大约阅读时间需要 7 分钟。

一、定义结构

   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;

     }

 

   }

转载地址:http://irjsi.baihongyu.com/

你可能感兴趣的文章
JAVA数据类型
查看>>
Xshell 4 入门
查看>>
SoapUI-入门
查看>>
Oracle -常用命令
查看>>
JAVA技术简称
查看>>
ORACLE模糊查询优化浅谈
查看>>
2016——个人年度总结
查看>>
2017——新的开始,加油!
查看>>
【Python】学习笔记——-6.2、使用第三方模块
查看>>
【Python】学习笔记——-7.0、面向对象编程
查看>>
【Python】学习笔记——-7.1、类和实例
查看>>
【Python】学习笔记——-7.2、访问限制
查看>>
【Python】学习笔记——-7.3、继承和多态
查看>>
【Python】学习笔记——-7.4、获取对象信息
查看>>
【Python】学习笔记——-7.5、实例属性和类属性
查看>>
Linux设备模型(总线、设备、驱动程序和类)之四:class_register
查看>>
git中文安装教程
查看>>
虚拟机 CentOS7/RedHat7/OracleLinux7 配置静态IP地址 Ping 物理机和互联网
查看>>
弱类型、强类型、动态类型、静态类型语言的区别是什么?
查看>>
Struts2技术内幕图书 转载
查看>>