IOCP相关问题和解决方案
来源:互联网 发布:mac版idown怎么用 编辑:程序博客网 时间:2024/06/08 14:28
IOCP 中的一些问题
1.连接建立
同步accept的问题是在连接建立时创建socket,对于大量连接同时建立的处理存在瓶颈。异步的acceptex可以预先创建好socket,等到连接建立时为连接分配一个socket,不存在同步情况下的瓶颈。做法是把监听的套接字和完成端口绑定,并对监听的套接字投递多个异步acceptex操作,在工作者线程中拿到完成消息并处理新建的客户端连接。
2.数据接收
投递多个接收操作,在工作者线程数量>1的情况下,接收到的数据需要处理乱序,性价比不好。选择对每个socket投递一个异步接收,在连接建立时和接收操作完成后投递。如果异步接收返回成功,说明已经有数据到达,此时工作者线程还是会收到完成通知的。这里只需处理异步接收出错并且错误号不是WSA_IO_PENDING这种情况,说明连接已经断开。
3.数据发送
数据发送存在的问题是缓冲区没有发送完全,即异步send准备发送2k,在完成通知里得知仅发送了1k,此时需要立即发送另外1k数据。做法是保持同一个socket未完成的发送操作<=1,为每个socket维护一个发送缓冲(重叠IO)队列和一个发送完成标志,每次在投递异步发送时检查标志,若目前是发送完成状态,直接投递异步发送数据;若目前是发送未完成状态,将要发送的重叠IO添加到缓冲队列尾部。在工作者线程中,收到发送完成通知后,若实际发送长度小于缓冲区长度,将未发送的部分重新投递发送操作,否则就取出发送缓冲队列首部的重叠结构并发送。若队列空,置发送完成标志为真。但是这样又需要对缓冲队列上锁,增加额外的开销。
以下是转载:
IOCP编程注意事项
1、每个连接同时最好只有一个待决的WSARecv。IOCP不保证多个待决WSARecv情况下先投递的WSARecv就一定会先得到完成通知。因此
,多个待决WSARecv可能导致数据乱序,无谓增加代码复杂性。
2、投递0长度缓冲区的WSARecv可以不占用非分页内存,避免WSAENOBUFS错误。
3、每个连接同时最好只有一个待决的WSASend。发送数据会锁定系统费非分页内存,过多的WSASend会导致WSAENOBUFS错误,麻烦的事
情。
4、WSASend直接返回成功,说明数据已复制到发送缓冲区;若WSA_IO_PENDING,则当得到完成通知时,不会出现只发送部分数据的情
况(本人未具体研究,只是别人看了泄露的NT4.0的代码的得到的结论,为了万全,还是要考虑发送部分数据的情况,若出现发送部分数据情
况,那么一个连接投递多个WSASend就不行了,投递WSASend相当于追加发送缓冲区,滑动窗口未必会一次性更新)。
5、IOCP是为响应大规模并发连接,做到了1、2、3和4能够尽可能的增加连接并发数量:因为并发数量很大程度是由非分页内存的占用
量决定的。
6、服务端应该提供强制关闭和优雅关闭连接功能。推荐使用强制关闭,以避免socket的TIME_WAIT状态。
7、多多利用DisconnectEx函数实现socket 重用,因为socket的分配是有代价的。
8、当socket资源被释放后,若不存在TIME_WAIT状态,要警惕系统立即把该socket值分配给新的连接,这就导致资源释放与新旧
socket资源同步问题。建议socket出错后,先释放相关资源,再closesocket或者DisconnectEx。
9、DisconnectEx不能实现强制关闭:即使设置SO_LINGER选项,DisconnectEx也不会发出RST,只有FIN。
10、当新建一个连接后,要对新的socket设置SO_UPDATE_ACCEPT_CONTEXT选项,否则对其的shutdown和DisconnectEx会有WSAENOTCONN错误,算是个bug。
11、这个和强制关闭有关:取消已经投递的IO操作,可以使用的函数有CancelIO和CancelIOEx,具体区别参见MSDN。要注意,CancelIOEx需要Windows Server 2008及以上、Windows Vista及以上。
12、考虑提供接收和发送紧急数据的接口。
13、Overlapped(重叠)方式类似于zero-copy:直接锁定用户buffer至非分页内存。
14、调用DisconnectEx()成功后,socket仍然和先前的绑定的完成建一一对应,除非使用closesocket()。
15、当然直接closesocket()也可以取消已投递的IO操作,但是要注意到资源同步的问题、可能发生的socket资源再分配问题。
16、GetQueuedCompletionStatusEx()是个好函数:一次调用尽可能多的获得完成通知,减少用户态和内核态之间的切换
- IOCP相关问题和解决方案
- 【Docker】Docker push失败的问题相关解决方案和实践
- AGS的相关项目的问题和解决方案
- IOCP相关文章链接
- IOCP相关梳理
- KYLIX相关问题及解决方案
- js相关问题的解决方案
- 四个棘手的IOCP编码问题和解决方法
- IOCP相关的一些总结
- IOCP相关的一些总结
- IOCP相关的一些总结
- 使用Mencoder进行视频转换遇到的问题和相关解决方案
- IOCP和SetFileCompletionNotificationModes
- IOCP和SetFileCompletionNotificationModes
- select和iocp模式
- EPOLL和IOCP比较
- EPOLL和IOCP比较
- 新手DB2命令行相关问题以及解决方案
- 结构体的使用
- DB2的SQLCODE和SQLState相关解释
- delphi webbrowser 模拟表单提交
- javax.naming.InitialContext.lookup("java:comp/env/***")
- mysql int(3)与int(11)的区别
- IOCP相关问题和解决方案
- linux ant 自动打包
- Android学习之 反编译
- [Win8]Windows8开发笔记(十):FlipView和自定义值转换器
- 求子数组的最大和
- log4j.properties log4j 配置
- 2012微软暑期实习生笔试题
- 2013年3月23----使用Java I-Ol流快速搜索手机文件引擎
- RSYNC 所有的参数详解