连续性多个 WSASend() io 完成端口

Posted

技术标签:

【中文标题】连续性多个 WSASend() io 完成端口【英文标题】:continuity multiple WSASend() io compretion ports 【发布时间】:2016-07-07 09:37:07 【问题描述】:

在来自服务器的 IO 完成端口中使用 TCP,如果我在同一个套接字中创建两个连续的 WSASend,第一个发送“ABC”,第二个发送“DEF”,然后当我调用 GetQueuedCompletionStatus 它告诉我第一个WSASend 只发送了“AB”,然后我再次调用GetQueuedCompletionStatus,它告诉我第二个WSASend 发送了“DEF”,客户端是否要接收“ABDEF”?或者第二个WSASend 会因为第一个WSASend 消息不完整而失败?

【问题讨论】:

这应该是不可能的。部分写入只应在发生致命事件时发生,从而完全阻止后续写入取得任何进展。你确定你没有按顺序处理完成吗? (虽然操作必须按开始的顺序完成,但不能保证您会按顺序接收/处理完成指示。) 我做的例子只是虚构的,所以我可以理解io完成端口是如何工作的。那么如果WSASend发送了一个不完整的消息,是否意味着我应该关闭socket? 你可以关闭套接字。您还可以发布另一个发送并查看您收到的错误。如果您有一个待处理,您也可以等待接收错误。 换句话说,您可以将其视为错误条件。大概你已经检查了操作是否返回了错误代码;在这种情况下,无论你做什么,在这种情况下你都可以做到。 【参考方案1】:

接收方不会收到 ABDEF,因为这意味着违反了流的完整性。

如果您在 ABC 和 DEF(按此顺序)上发出 WSASend(),并且您获得 2 个字节的 ABC 和 3 个字节的 DEF 完成,则接收方可能什么也没有收到,A、AB、ABC、ABCD、ABCDE ,或 ABCDEF。不过很可能,他们没有收到 AB 以外的任何东西。

当 WSASend() 的完成指示除完整发送之外的任何内容时,您应该终止套接字。 closesocket() 确实是你应该做的最后一件事;在此之前,您应该清空所有未完成的发送和接收(CancelIoEx()、shutdown() 等)。

【讨论】:

以上是关于连续性多个 WSASend() io 完成端口的主要内容,如果未能解决你的问题,请参考以下文章

菜鸟 关于WSASend 函数,IO完成端口模型

具有多个缓冲区的 WSASend() - 可以完成不完整吗?

IOCP:内核如何决定同步或异步完成 WSASend?

阻塞模式下的 WSASend() 是不是会导致将通知数据包放置在完成端口中?

是否有可能不会收到 WSASend 调用的完成?

如何知道完成数据包是针对 WSASend() 还是 WSARecv() 还是 AcceptEx()?