关于IOCP中是否可以对同一socket连续投递的疑问已经很久了,主要的疑问在wsaSend是否可以保证数据的完整发送,是否会出现部分发送成功的情况?
网上大多数的建议都是WSASEND采用线性模式,即建立一个发送缓冲,当上一次send完成之后,再进行下一次的投递。那么WSASEND什么情况下会出现部分发送呢?
在MSDN中IOCP的列子是对得到的发送的字节值进行了判断的,而在wsaSend函数的描述中也有这样一句:Note The successful completion of a WSASend does not indicate that the data was successfully delivered.
我首先想到的是当发送缓冲区不足的时候,会不会造成wsaSend部分发送返回。做了个实验,连续发送10M的数据(肯定大于缓冲区了)。第一次直接返回成功(对端并未进行Recv),第二次返回IO_PENDING.看来不是这样的。查了《windows 网络编程技术》其中有这样一段话:
When an application makes a send call, if there is sufficient buffer space, the data is copied into the socket's send buffers, the call completes immediately with success, and the completion is posted. On the other hand, if the socket's send buffer is full, then the application's send buffer is locked and the send call fails withWSA_IO_PENDING. After the data in the send buffer is processed (for example, handed down to TCP for processing), then Winsock will process the locked buffer directly. That is, the data is handed directly to TCP from the application's buffer and the socket's send buffer is completely bypassed。
当发送缓冲不足的时候,会内存锁定,我另一端调用recv,收到wsasend的完成信号时,发送的字节数=要发送的字节数,并没有部分发送。
下面是我网上找到的一片帖子忘了出自哪里了。
---------------------------------------------------------------------------------------------------------