IOCP中在WSASend以及WSARecv的时候出现WSA_IO_PENDING情况的说明
网络编程 2010-08-11 11:05:53 阅读293 评论0 字号:大中小 订阅
应该是windows网络编程第二版里面提到过。现在整理一下。
1:在IOCP中投递WSASend返回WSA_IO_PENDING的时候,表示异步投递已经成功,但是稍后发送才会完成。这其中涉及到了三个缓冲区。
网卡缓冲区,TCP/IP层缓冲区,程序缓冲区。
情况一:调用WSASend发送正确的时候(即立即返回,且没有错误),TCP/IP将数据从程序缓冲区中拷贝到TCP/IP层缓冲区中,然后不锁定该程序缓冲区,由上层程序自己处理。TCP/IP层缓冲区在网络合适的时候,将其数据拷贝到网卡缓冲区,进行真正的发送。
情况二:调用WSASend发送错误,但是错误码是WSA_IO_PENDING的时候,表示此时TCP/IP层缓冲区已满,暂时没有剩余的空间将程序缓冲区的数据拷贝出来,这时系统将锁定用户的程序缓冲区,按照书上说的WSASend指定的缓冲区将会被锁定到系统的非分页内存中。直到TCP/IP层缓冲区有空余的地方来接受拷贝我们的程序缓冲区数据才拷贝走,并将给IOCP一个完成消息。
情况三:调用WSASend发送错误,但是错误码不是WSA_IO_PENDING,此时应该是发送错误,应该释放该SOCKET对应的所有资源。
2:在IOCP中投递WSARecv的时候,情况相似。
情况一:调用WSARecv正确,TCP/IP将数据从TCP/IP层缓冲区拷贝到缓冲区,然后由我们的程序自行处理了。清除TCP/IP层缓冲区数据。
情况二:调用WSARecv错误,但是返回值是WSA_IO_PENDING,此时是因为TCP/IP层缓冲区中没有数据可取,系统将会锁定我们投递的WSARecv的buffer,直到TCP/IP层缓冲区中有新的数据到来。
情况三:调用WSARecv错误,错误值不是WSA_IO_PENDING,此时是接收出错,应该释放该SOCKET对应的所有资源。
在以上情况中有几个非常要注意的事情:
系统锁定非分页内存的时候,最小的锁定大小是4K(当然,这个取决于您系统的设置,也可以设置小一些,在注册表里面可以改,当然我想这些数值微软应该比我们更知道什么合适了),所以当我们投递了很多WSARecv或者WSASend的时候,不管我们投递的Buffer有多大(0除外),系统在出现IO_PENGDING的时候,都会锁定我们4K的内存。这也就是经常有开发者出现WSANOBUF的情况原因了。
我们在解决这个问题的时候,要针对WSASend和WSARecv做处理
1:投递WSARecv的时候,可以采用一个巧妙的设计,先投递0大小Buf的WSARecv,如果返回,表示有数据可以接收,我们开启真正的recv将数据从TCP/IP层缓冲区取出来,直到WSA_IO_PENGDING.
2:对投递的WSARecv以及WSASend进行计数统计,如果超过了我们预定义的值,就不进行WSASend或者WSARecv投递了。
3:现在我们应该就可以明白为什么WSASend会返回小于我们投递的buffer空间数据值了,是因为TCP/IP层缓冲区小于我们要发送的缓冲区,TCP/IP只会拷贝他剩余可被Copy的缓冲区大小的数据走,然后给我们的WSASend的已发送缓冲区设置为移走的大小,下一次投递的时候,如果TCP/IP层还未被发送,将返回WSA_IO_PENGDING。
4:在很多地方有提到,可以关闭TCP/IP层缓冲区,可以提高一些效率和性能,这个从上面的分析来看,有这个可能,要实际的网络情况去实际分析了。
分享到:
相关推荐
IO完成端口文件读写操作\IO完成端口文件读写操作
一个很好用的完成端口类,效率超高。欢迎下载。
一个IOCP程序的例子 一个IOCP程序的例子 共享一下。。
VC++ IOCP反弹远控客户端模型源代码+注释
包括了用vc++开发iocp的整体方案,比使用select模型要好得多
完成端口是最高效的windows处理方式,这个是完成端口的通讯控件for delphi,可能不是很完善,可以参考
传说中的io完成端口,具有性能高的特点,是windows中性能最好的网络通信模型,这个是iocp的类。。。。。。。。。。。。。。。。。。。
然而,当一个事件发生的时候,此完成端口就将被操作系统加入一个队列中。然后应用程序可以对核心层进行查询以得到此完成端口。此资料是对IOCP模型的深入讲解及总结,让你能更清楚的了解IOCP模型工作的本质。
利用完成端口(IOCP)实现的在线网络考试系统的客户端程序。
windows 网络编程IOCP的应用。简单的实例。
2008/11/15号最新版本,以封装类形式提供TCP IOCP功能,改进先前版本的不足,以及BUG,增加UDP IOCP功能,增加了互斥访问的代码量,提高了运行稳定性;提供MFC扩展DLL(带lib和.h文件)
这是一个用完成端口(IO Completion port)写的echo server,运行iocp.exe后,在控制台使用 telnet 127.0.0.1 7 就可以连接上,然后你输入什么屏幕就显示什么。
Socket通讯中服务端的性能最高的实现方法:完成端口,
源码使用了高级的完成端口(IOCP)技术,该技术可以有效地服务于多客户端。代码封装了IOCP并提供了一个简单的echo版本的可以传输文件的客户端/服务器程序
IOCP_原理_代码 IOCP_原理_代码
网上找来的IOCP资料,希望对从事这方面的朋友有帮助。
delphi iocp 最 简 单 封 装
完成端口功能说明:实现服务器发送结构体到客户端,接收后进行解析,获取发送的结构数据,并显示在IDC_LOGG控件里
http://download.csdn.net/my/uploads 稍加改动
IOCP_IOCP百万级别_partyeoq_IOCP_源码.zip