- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
WinSocket模型的探讨——完成端口模型
众所皆知,完成端口是在WINDOWS平台下效率最高,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显示出其威力。其实建立一个完成端口的服务器也很简单,只要注意几个函数,了解一下关键的步骤也就行了。
这是篇完成端口入门级的文章,分为以下几步来说明完成端口:
函数
常见问题以及解答
步骤
例程
1、函数:
我们在完成端口模型下会使用到的最重要的两个函数是:
CreateIoCompletionPort、GetQueuedCompletionStatus
CreateIoCompletionPort 的作用是创建一个完成端口和把一个IO句柄和完成端口关联起来:
// 创建完成端口
HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
// 把一个IO句柄和完成端口关联起来,这里的句柄是一个socket 句柄
CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)PerHandleData, 0);
其中第一个参数是句柄,可以是文件句柄、SOCKET句柄。
第二个就是我们上面创建出来的完成端口,这里就把两个东西关联在一起了。
第三个参数很关键,叫做PerHandleData,就是对应于每个句柄的数据块。我们可以使用这个参数在后面取到与这个SOCKET对应的数据。
最后一个参数给0,意思就是根据CPU的个数,允许尽可能多的线程并发执行。
GetQueuedCompletionStatus 的作用就是取得完成端口的结果:
// 从完成端口中取得结果
GetQueuedCompletionStatus(CompletionPort, BytesTransferred, (LPDWORD)PerHandleData, (LPOVERLAPPED*)PerIoData, INFINITE)
第一个参数是完成端口
第二个参数是表明这次的操作传递了多少个字节的数据
第三个参数是OUT类型的参数,就是前面CreateIoCompletionPort传进去的单句柄数据,这里就是前面的SOCKET句柄以及与之相对应的数据,这里操作系统给我们返回,让我们不用自己去做列表查询等操作了。
第四个参数就是进行IO操作的结果,是我们在投递 WSARecv / WSASend 等操作时传递进去的,这里操作系统做好准备后,给我们返回了。非常省事!!
个人感觉完成端口就是操作系统为我们包装了很多重叠IO的不爽的地方,让我们可以更方便的去使用,下篇我将会尝试去讲述完成端口的原理。
2、常见问题和解答
a、什么是单句柄数据(PerHandle)和单IO数据(PerIO)
单句柄数据就是和句柄对应的数据,像socket句柄,文件句柄这种东西。
单IO数据,就是对应于每次的IO操作的数据。例如每次的WSARecv/WSASend等等
其实我觉得PER是每次的意思,翻译成每个句柄数据和每次IO数据还比较清晰一点。
在完成端口中,单句柄数据直接通过GetQueuedCompletionStatus 返回,省去了我们自己做容器去管理。单IO数据也容许我们自己扩展OVERLAPPED结构,所以,在这里所有与应用逻辑有关的东西都可以在此扩展。
b、如何判断客户端的断开
我们要处理几种情况
1) 如果客户端调用了closesocket,我们就可以这样判断他的断开:
if(0 == GetQueuedCompletionStatus(CompletionPort, BytesTransferred, 。。。)
{
}
if(BytesTransferred == 0)
{
// 客户端断开,释放资源
}
2) 如果是客户端直接退出,那就会出现64错误,指定的网络名不可再用。这种情况我们也要处理的:
if(0 == GetQueuedCompletionStatus(。。。))
{
if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
{
// 客户端断开,释放资源
}
}
3、步骤
编写完成端口服务程序,无非就是以下几个步骤:
1、创建一个完成端口
2、根据CPU个数创建工作者线程,把完成端口传进去线程里
3、创建侦听SOCKET,把SOCKET和完成端口关联起来
4
您可能关注的文档
最近下载
- 2025-2026学年粤教粤科版(2024)小学科学三年级上册(全册)教学设计(附目录 P182) .docx
- 电机拖动应用技术第2章知识点回顾总结.docx VIP
- 蓝光BL及BL培训总汇讲解.ppt VIP
- Q SY 17816-2021 泡沫驱用起泡剂技术规范.pdf VIP
- SL∕T 619-2021 水利水电工程初步设计报告编制规程.pdf
- 蓝光BL及BL培训总汇演示文稿.ppt VIP
- 第三单元:测量(单元复习课件-)人教版三年级数学上册.pptx VIP
- 巨人通力GPS53K(SIEI)-YH_电气原理图纸G3001007(B)N-2020-12.pdf
- 第1单元第5课《图片的局部处理》课件【滇人版】《信息科技》五年级上册.pptx VIP
- 《物业服务模式》课件.ppt VIP
原创力文档


文档评论(0)