2019独角兽企业重金招聘Python工程师标准>>>

主线程创建监听套接字,创建额外工作线程,关联IOCP,负责等待和接受到来的连接。

调用GetQueuedCompletionStatus函数,函数返回:

1 调用失败

2 套接字被对方关闭

3 请求成功完成

程序首先定义per-handle per-IO的操作数据的结构类型

#define BUFFER_SIZE 1024
typedef struct _PER_HANDLE_DATA{SOCKET s;sockaddr_in addr;
}PER_HANDLE_DATA,*PPER_HANDLE_DATA;
typedef struct _PER_IO_DATA{OVERLAPPED ol;char buf[BUFFER_SIZE];int nOperationType;
#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3
}PER_IO_DATA,*PPER_IO_DATA;


主要过程:

1 主线程创建完成端口对象,创建工作线程处理完成端口对象中的事件

2 创建监听套接字,开始监听服务器端口

3 进入无限循环,处理到来的请求

  1)调用accept函数等待接受未决的连接请求   2)创建一个per-handle数据   3)投递一个接收请求

实现代码:

void  main()
{int nPort = 4567;HANDLE hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE,0,0,0);::CreateThread(NULL,0,ServerThread,(LPVOID)hCompletion,0,0);SOCKET sListen = ::socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN si;si.sin_family = AF_INET;si.sin_port = htons(nPort);si.sin_addr.S_un.S_addr = INADDR_ANY;::bind(sListen,(sockaddr*)&si,sizeof(si));::listen(sListen,5);while(TRUE){//等待接收未决的请求
        SOCKADDR_IN saRemote;int nRemoteLen = sizeof(saRemote);SOCKET sNew = ::accept(sListen,(sockaddr*)&saRemote,&nRemoteLen);//创建per-handlePPER_HANDLE_DATA pPerHandle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA));pPerHandle->s = sNew;memcpy(&pPerHandle->addr,&saRemote,nRemoteLen);::CreateIoCompletionPort((HANDLE)pPerHandle->s,hCompletion,(DWORD)pPerHandle,0);//投递一个接收请求PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR,sizeof(PER_IO_DATA));pPerIO->nOperationType = OP_READ;WSABUF buf;buf.buf = pPerIO->buf;buf.len = BUFFER_SIZE;DWORD dwRecv;DWORD dwFlags = 0;::WSARecv(pPerHandle->s,&buf,1,&dwRecv,&dwFlags,&pPerIO->ol,NULL);//接收投递求
    }
}
DWORD WINAPI ServerThread(LPVOID lpParam{HANDLE hCompletion = (HANDLE)lpParam;DWORD dwTrans;PPER_HANDLE_DATA pPerHandle;PPER_IO_DATA pPerIO;while(TRUE){BOOL bOK = ::GetQueuedCompletionStatus(hCompletion,&dwTrans,(LPDWORD)&pPerHandle,(LPOVERLAPPED*)&pPerIO,WSA_INFINITE);if(!bOK){::closesocket(pPerHandle->s);::GlobalFree(pPerHandle);::GlobalFree(pPerIO);continue;}if(dwTrans == 0 && (pPerIO->nOperationType==OP_READ||pPerIO->nOperationType==OP_WRITE)){::closesocket(pPerHandle->s);::GlobalFree(pPerHandle);::GlobalFree(pPerIO);continue;}switch(pPerIO->nOperationType){case OP_READ:{pPerIO->buf[dwTrans] = '\0';printf(pPerIO->buf);WSABUF buf;buf.buf = pPerIO->buf;buf.len = BUFFER_SIZE;pPerIO->nOperationType = OP_READ;DWORD nFlags = 0;::WSARecv(pPerHandle->s,&buf,1,&dwTrans,&nFlags,&pPerIO->ol,NULL);}break;case OP_WRITE:case OP_ACCEPT:break;}}return 0;
}

转载于:https://my.oschina.net/u/204616/blog/544959

IOCP模型TCP服务器相关推荐

  1. 完整的IOCP模型 Echo服务器及代码分析

    首先,先感谢http://www.cnblogs.com/talenth/p/7068392.html 这篇博文,作者写的通俗易懂,语言幽默,偶然一次在公交车上见到这篇博文相见恨晚,一口气读下来很长一 ...

  2. 《ASCE1885的源码分析》の基于完成端口模型的TCP服务器框架

    使用IOCP的TCP服务器使用过程大体如下: 1)  使用CreateIoCompletionPort函数创建完成端口,并以该I/O完成端口为参数创建多个服务线程: 2) 创建监听套接字: 3) 接收 ...

  3. 基于select模型的TCP服务器

    之前的一篇博文是基于TCP的服务器和客户机程序,今天在这我要实现一个基于select模型的TCP服务器(仅实现了服务器). socket套接字编程提供了很多模型来使服务器高效的接受客户端的请求,sel ...

  4. reactor线程模型_从TCP服务器到I/O模型,带你学习Netty

    学习Netty就不得不从TCP服务器和I/O模型说起,了解TCP服务器架构和I/O模型的演进有助于深入了解Netty. TCP服务器的架构 一般地,TCP服务器有两种套接字,监听套接字和已连接套接字. ...

  5. [C/C++后端开发学习] 7 tcp服务器的epoll实现以及Reactor模型

    tcp服务器的epoll实现以及Reactor模型 1 IO多路复用 select poll epoll 2 epoll详解 2.1 基本使用方法 2.2 LT水平触发和ET边沿触发 2.3 实现服务 ...

  6. Server Develop (八) IOCP模型

    IOCP模型 IOCP全称I/O Completion Port,中文译为I/O完成端口.IOCP是一个异步I/O的Windows API,它可以高效地将I/O事件通知给应用程序,类似于Linux中的 ...

  7. WinSock I/O 模型 -- IOCP 模型

    前言 IOCP 全称 Input/Ouput Completion Ports,中文中翻译一般为"完成端口",本文中我们使用 IOCP 简写. IOCP 模型是迄今为止最为复杂的一 ...

  8. IOCP模型C++入门级服务端搭建

    IOCP模型C++入门级服务端搭建 效果展示 Windows平台打开DOS界面(cmd命令)输入:netstat -anot | findstr 端口号,即可查看端口是否被占用. 源码示例 TIPS: ...

  9. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器

    MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...

最新文章

  1. 文件查找利器---find详解
  2. 如何在linux服务器上使用hanlp
  3. 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化
  4. xml与java对象转换 -- XStreamAlias
  5. python中用于绘制各种图形的区域称作_Python--matplotlib绘图可视化知识点整理(示例代码)...
  6. 二年级计算机认识键盘教案,认识计算机键盘教案.doc
  7. 身份证合法验证查询易语言代码
  8. 交通灯c语言单片机课程设计,交通灯单片机课程设计C语言.doc
  9. R 语言的安装(详细教程)
  10. 一款神仙儿 MySQL 审核平台,吊到不行!
  11. somachineV4.1的注册
  12. Mose机器翻译Ubuntu18配置和遇到的问题
  13. windows下python安装basemap,画世界地图以及根据经纬度标点
  14. 全能IDE VsCode
  15. dhcp snooping华为_华为交换机DHCP snooping
  16. 如何正确使用物业安全巡检系统
  17. Suzy想吃烤蛋挞了Day35 | 贪心算法进行时:860. 柠檬水找零,406. 根据身高重建队列,452. 用最少数量的箭引爆气球
  18. error:expected '{' at end of input
  19. 请问 e^π 和 π^e 哪个大?
  20. 极大似然估计的理解 为什么要取似然函数最大值 似然函数的意义是什么?

热门文章

  1. Android中TableLayout如何让列自动换行
  2. 飞利浦医疗收购Direct Radiology,加强远程放射学服务能力
  3. python接口自动化(二十八)--html测试 报告——下(详解)
  4. api postmain 鉴权_API授权与验证 - 文档中心 - 快代理
  5. c语言程序机试题及答案,C语言程序设计试题及答案解析(二)
  6. php zend mvc 配置,理解Zend Framework 的MVC模式_PHP教程
  7. win 10 1709安装linux,小编详解win10 1709安装教程
  8. oracle索引可以加到in,为什么你加的索引不管用?
  9. 【第1篇】Python爬虫实战-王者荣耀高清壁纸下载
  10. linux下启动tomcat,Cannot find setclasspath.sh