1

有什么方法可以检查使用winsock 的send() 或WSASend() 发送的数据是否真的传送到目的地?

我正在编写一个与第三方服务器通信的应用程序,它有时会在工作一段时间后出现故障,并且需要确定发送到该服务器的消息是否已传递。问题有时是调用 send() 完成时没有错误,即使服务器已经关闭,并且只有下一个 send() 完成时出错 - 所以我不知道之前的消息是否已传递。

我想在 TCP 层上有信息是否发送的某些(或所有)数据包被确认,但使用套接字接口不可用(或者我找不到方法)。

最糟糕的是,我无法更改服务器的代码,因此我无法收到任何交付确认消息。

4

2 回答 2

0

不是从返回到 send()。所有 send() 都说数据被推入发送缓冲区。连接的套接字流不能保证发送所有数据,只是保证数据是有序的。因此,您不能假设您的 send() 将在单个数据包中完成,或者它是否会由于网络延迟或中断而发生。

如果您需要完整的确认,则必须查看更高的应用程序级别的确认(服务器发送回格式化的确认消息,而不仅仅是数据包确认)。

于 2011-01-26T22:39:35.887 回答
0

很抱歉,但鉴于您要实现的目标,您应该意识到,即使 TCP 堆栈可以向您指示远程 TCP 堆栈已确认特定的一组字节,它实际上也不会意味着与您目前所知道的任何不同的东西。

问题是,除非您有来自远程应用程序的应用程序级 ACK,该 ACK 仅在远程应用程序对您发送给它的数据进行操作后才发送,否则您将永远无法确定远程应用程序是否已接收到数据.

“但我可以假设它足够接近”

只是妄想。如果您的发送完成,您也可以做出这样的假设,因为它几乎是有效的。

问题是,即使 TCP 堆栈可以告诉您远程堆栈已确认数据 (1),这与接收数据的远程应用程序不同 (2),也与远程应用程序不同应用程序实际使用数据 (3)。

鉴于远程应用程序可能在任何时候崩溃,1、2 或 3 唯一有价值的数据已到达指示是远程应用程序在将数据用于预期目的后发送的指示。

其他一切都只是一厢情愿。

于 2011-01-27T08:28:43.533 回答