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层缓冲区,可以提高一些效率和性能,这个从上面的分析来看,有这个可能,要实际的网络情况去实际分析了。
分享到:
相关推荐
5. “IOCP中在WSASend以及WSARecv的时候出现WSA_IO_PENDING情况的说明 - 服务器开发(Server Development) - 服务器开发 UDP服务器开发 TCP服务器开发 游戏服务器开发 IOCP 服务器设计.htm”:文章可能涉及了在使用...
在描述中提到的"IOCP.rar_IOCP_UCode io_delphi iocp_iocp delphi_完成端口",这是一个针对Delphi开发的完成端口通讯控件。虽然可能不完全完善,但它为开发者提供了一个基础框架,便于理解和实现基于IOCP的通信机制...
标题中的"IOCP.rar_IOCP_io_iocp vc_vc iocp"暗示了这是一个关于Windows平台下使用IO完成端口(Input/Output Completion Port, IOCP)技术的开发资源包,主要面向VC++(Visual C++)编程环境。IOCP是Windows系统中...
标签中的“_iocp-server”、“iocp”、“iocp_文件”、“io”和“完成端口”进一步强调了这个话题集中在IO完成端口技术,尤其是关于文件操作的实现。IOCP通常用于网络服务,例如HTTP服务器、FTP服务器,以及任何需要...
在Windows系统中,I/O操作通常涉及大量的等待和同步,这可能会导致CPU资源的浪费。为了解决这个问题,Microsoft引入了一种高效的I/O模型——I/O完成端口(IOCP,Input/Output Completion Port),它允许多个线程并发...
一个IOCP程序的例子 一个IOCP程序的例子 共享一下。。
VC++ IOCP反弹远控客户端模型源代码+注释
在Windows操作系统中,I/O Completion Ports(IOCP)是一种高效的多线程I/O处理机制,尤其适用于高并发的网络服务器。本文将详细讲解C语言如何实现基于IOCP的程序设计,以及IOCP的工作原理和优势。 一、IOCP概念 ...
标题中的"IOCP.rar_C++ iocp_DEMO_Gh0st_IOCP socket"表明这是一个关于C++实现的IO Completion Ports (IOCP)技术的示例项目,可能包含了一个名为"Gh0st"的特定IOCP服务器或客户端的源代码。IOCP是Windows操作系统中...
标题中的“IOCP.rar_IOCP_IOCP 封装_传输文件_完成端口_服务器”表明这个压缩包包含了关于IOCP(I/O Completion Port,I/O完成端口)技术的实现,特别是关于如何封装IOCP以及如何用它来构建一个能够传输文件的服务器...
【标题】"iocp.rar.rar_IOCP_iocp库_iocp线程池_系统服务_网络监控"涉及的关键技术是IO完成端口(IOCP,Input/Output Completion Port),这是Windows操作系统中的一种高效率的异步I/O模型,常用于网络服务器的构建...
- 在处理线程中,使用WSASend和WSARecv进行数据发送和接收,利用IOCP完成异步操作。 四、IOCP客户端实现 客户端的实现相对简单,主要包括: - 创建连接套接字,设置为非阻塞模式。 - 连接到服务器,将连接套接字与...
PUDN是一个分享编程资源和技术讨论的平台,这里的“pudn_iocp”标签可能指的是在该社区中有关IOCP的资源或问题解答。 使用IOCP时需要注意以下几点: 1. **线程池管理**:为了处理来自IOCP的完成通知,需要维护一个...
标题中的"IOCP_client.rar"指的是一个使用了IOCP(I/O完成端口)技术的客户端程序,主要用于网络考试系统。这个压缩包包含了项目开发所需的源代码和其他相关文件,让我们来详细了解一下IOCP以及它在构建网络考试...
2. 文档:详细解释IOCP的工作原理、API用法,以及如何在.NET环境中适配。 3. 实例分析:可能包含一些实际案例,例如创建一个简单的HTTP服务器,展示IOCP如何处理并发请求。 学习和理解IOCP,不仅可以提升.NET应用在...
本文将深入探讨标题和描述中提及的"完成端口",以及其在Socket通讯中的应用,特别是作为服务端性能优化的一种高效实现方式。 完成端口是Windows操作系统提供的一种高级I/O模型,用于处理大量并发I/O操作。它基于...
if (WSARecv(socket, &buf, 1, &bytes_transferred, NULL, &overlap, NULL) == 0 || WSAGetLastError() == WSA_IO_PENDING) { // 提取完成的I/O ULONG completed_key; GetQueuedCompletionStatus(io_port, &bytes...
标题中的"IOCP.rar"指的是一个使用了IOCP(I/O完成端口)技术的示例项目,而"IOCP M_IOCPModule_iocp mfc_mfc IOCP_visual c"进一步强调了这个示例是关于MFC(Microsoft Foundation Classes)框架下的IOCP模块,使用...
在IT行业中,IOCP(I/O完成端口)是一种高效的异步I/O模型,尤其适用于高并发、低延迟的应用场景。Delphi是Object Pascal的一种现代实现,它提供了一个强大的编程环境来开发Windows应用程序。本篇文章将深入探讨如何...
在IOCP模型中,服务器创建一个或多个完成端口,并绑定监听套接字,用于接收客户端连接请求。一旦有新的连接建立,服务器会为每个连接分配一个单独的工作线程,这个线程通过调用`GetQueuedCompletionStatus`函数等待...