2011-01-26 39 views
1

有没有任何方法检查使用winsock的send()或WSASend()发送的数据是否确实传送到目的地?确保发送()数据已发送

我正在写一个应用程序与第三方服务器交谈,这个服务器在工作一段时间后有时会关闭,并且需要确定发送到该服务器的消息是否已发送。问题是有时候调用send()完成没有错误,即使服务器已经关闭,只有下一个send()完成时出现错误 - 所以我不知道以前的消息是否已经传递。我想在TCP层有信息,如果某些(或所有)发送的数据包是acked或不是,但它不是使用套接字接口(或我找不到方法)。

最糟糕的是,我无法更改服务器的代码,所以我无法获得任何传送确认消息。

回答

0

对不起,但考虑到你要实现的目标,你应该认识到,即使TCP堆栈可以给你一个特定的字节集已被远程TCP堆栈确认的指示,实际上并不意味着与你目前所知道的有任何不同。

问题是,除非您从远程应用程序获得应用程序级别的确认,只有在远程应用程序已对您发送给它的数据执行操作后才会发送确认,否则您将永远无法确定是否已收到数据由远程应用程序。

'但我可以假设它的足够接近'

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

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

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

其他一切都只是一厢情愿的想法。

0

不是从返回发送()。所有的send()都表示数据被压入发送缓冲区。连接的套接字流不保证发送所有数据,只是数据将按顺序发送。所以你不能假设你的send()将在一个数据包中完成,或者由于网络延迟或中断而发生。

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

+0

TCP协议有瑕疵,所以TCP层完全知道对方是否收到已发送消息的一部分 - 是否有任何获取此信息的选项?我知道通过其他TCP堆栈来完成消息并不意味着读取它并按应用程序进行处理,但我可以假设它足够接近。作为第三方服务器,我无法修改应用程序协议。 – miara 2011-01-27 07:04:05

+0

该信息不会传播回API,正如您所说的那样,并不意味着服务器将其从*它的缓冲区中读出并处理。 – CoreyStup 2011-01-27 13:36:26