IOCP服务器WSASend的疑惑

ringphone 2005-10-08 11:27:54
MSDN里面的说明:
The array of WSABUF structures pointed to by the lpBuffers parameter is transient. If this operation is completed in an overlapped manner, it is the service provider's responsibility to capture these WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays.
Note The successful completion of a WSASend does not indicate that the data was successfully delivered.

意思是提交的数据在WSASend后就可以挪作他用或销毁,即可以象如下方式调用:
void SendData()
{
char data[100];
sprintf(data,"something to send");
WSASend(...)
};
看起来WSASend是会把数据复制一份自己保存,试了下,分配1M的缓冲区,读取一个三四百K的文本,一次性把数据WSASend出去,然后立马销毁该缓冲区,客户端是能完整收到所有数据的。
但是我疑惑的是上面MSDN里最后一句话,WSASend不保证数据成功提交,意思是不是这样调用会丢包呢?那就无法体现TCP的可靠性了。这种情况下如果GetQueuedCompletionStatus检测到发送的字节数与要发送的不一致,没办法处理了,因为发送的数据已不存在了。那MSDN又为什么说可以销毁数据呢?
...全文
1127 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdf123321 2006-04-12
  • 打赏
  • 举报
回复
GZ
ringphone 2005-10-09
  • 打赏
  • 举报
回复
刚才又试了一下,实际情况是这样的:服务器端读一个300K的文本(小说),WSASend,紧跟着销毁缓冲区。然后调试客户端,在recv上打断点,把收到的数据存成文件。VC中断的时候服务器肯定是WSASend了数据并且销毁了缓冲区,而这时客户端还没接收数据,这时候按F10慢慢收吧,能收全数据,把存盘的文件与服务器端读的原始文件用UltraEdit比较,是完全一样的。而客户端调试过程中服务器端的GetQueuedCompletionStatus早就收到了发送完毕的事件并且发送字节数就是文件尺寸。看来WSASend只是把数据放到了TCP底层的发送缓冲区,而这些数据是要客户端去收的,因此说不保证数据到达客户端。
nuaawenlin 2005-10-09
  • 打赏
  • 举报
回复
send,WSASend只保证把用户缓冲区里面的数据拷贝到系统缓冲区,不是把数据发送到对方
一次能拷贝多少,依据你的机器情况。
所以在Send,WSASend之后,要获得返回值,判断一下,有多少用户缓冲区的字节成功的拷贝到了系统缓冲区,以便把没有拷贝的自己,在下次指定拷贝进去

tcp有自己的发送窗口算法,有重发机制,只要不是网络断开,数据都能可靠的到达对方。详细参考tcp/ip详解
ringphone 2005-10-09
  • 打赏
  • 举报
回复
以上结果是在两台机器上试的。
zhxk 2005-10-09
  • 打赏
  • 举报
回复
建议你在两台机子上试,避免函数旁路

sevencat 2005-10-09
  • 打赏
  • 举报
回复
假如用IOCP的话,WSASend在你没接到完成端口的消息前,不要移做他用,虽然你判断返回值可能已经成功了,但这样增加编程的负担的呀。
lifengice0706 2005-10-08
  • 打赏
  • 举报
回复
说说我自己的理解:msdn中提到的The successful completion of a WSASend does not indicate that the data was successfully delivered.表示如,当你用wsasend()提交了1024个字节的数据时,wsasend()并不能保证在GetQueuedCompletionStatus()处理到完成消息时,就发出了1024个字节,可能小于1024,因为GetQueuedCompletionStatus()返回了这次完成的字节数,当返回的数字小于1024时,你需要后移发送缓冲区的指针,用wsasend()完成剩余数据的发送。所以在第一段中的completed指的是发送完了你要求发送的字节数。然后在销毁!

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧