查找是否传递了一个通过tcp的消息

当我通过tcpstream发送()/写入()一条消息时,如何才能找出这些字节是否成功传递?

接收方确认通过tcp接收字节,所以发送方tcp堆栈应该知道。

但是当我发送()一些字节时,send()立即返回,即使数据包不能被传递,我在netcat上使用stracetesting了在Linux 2.6.30上,在发送一些字节之前拉出networking电缆。

我正在开发一个应用程序,在这个应用程序中,知道消息是否被传递是非常重要的,但是实现tcpfunction(“消息#123”)感到尴尬,必须有更好的方法。

Solutions Collecting From Web of "查找是否传递了一个通过tcp的消息"

发送TCP确实知道数据何时被另一端确认,但是这样做的唯一原因是它知道何时可以丢弃数据(因为其他人现在负责将数据提交给另一端的应用程序)。

它通常不会将这些信息提供给发送应用程序,因为(尽管出现)对于发送应用程序实际上并不意味着太多。 确认并不意味着接收的应用程序已经获得了数据并且做了一些明智的事情 – 所有这一切意味着发送TCP不再需要担心。 数据仍可能在传输中 – 例如,在中间代理服务器中,或在接收TCP堆栈中。

“数据成功接收”实际上是一个应用程序级的概念,它的含义取决于应用程序(例如,对于许多应用程序来说,只有在接收到的数据被同步到磁盘后才考虑数据“接收”侧)。 所以这意味着你必须自己实现它,因为作为应用程序开发人员,你真的是唯一知道如何为你的应用程序明智地做到这一点的人。

让接收方回复一个确认是最好的方法,即使它“感到尴尬”。 请记住,IP可能会将数据分解为多个数据包并重新组装,如果路由器中的各个路由器具有不同的MTU,则可能会在传输过程中多次执行此操作,所以您的“数据包”和TCP的概念可能不一致。

最好发送你的“数据包”,不管它是一个字符串,一个序列化的对象还是二进制数据,并让接收者做它需要做的任何检查,然后发回一个确认。

TCP协议会尽力确保您的数据到达。 如果出现网络问题,将重传数据。 这意味着您发送的任何内容都会被缓冲,并且没有及时的方法来确保它已经到达(如果网络关闭,2分钟后会有一个超时)。

如果您需要快速反馈,请使用UDP协议。 它不使用任何TCP开销,但你必须自己处理所有的问题。

应用层不能控制低层(比如传输层)的通知,除非它们是专门提供的 – 这是设计的。 如果你想知道TCP在每个数据包级别上做了什么,你需要在TCP层运行的层上找到。 这意味着处理TCP头和ACK数据。

但是,最终用来承载有效负载的任何协议都可以用来通过该有效负载来回传递消息。 所以,如果你觉得使用TCP头部的位来做到这一点很尴尬,只需在你的应用程序中设置它。 例如:

A: Send 450 Bytes B: Recv 450 Bytes B: Send 'I got 450 Bytes' A: Recv 'B got the full message' A: Continue 

即使它达到了TCP层,也不能保证它不在应用程序的缓冲区中,那么应用程序就会崩溃,然后才能处理它。 使用确认,这就是所有其他的事情(例如SMTP)

这听起来像是SCTP可以看的东西; 我认为它应该支持你想要的。 替代似乎是切换到UDP,如果你正在切换协议…