TCP是否百分之百可靠?

3
尽管TCP是一种可靠的协议,提供了重传和确认机制,但我认为它并不是100%可靠的,因为send()成功返回并不能确保数据已经到达目标端点,只意味着数据被复制到内核缓冲区。
应用程序有没有机制可以知道数据是否已成功到达目的地?
一个可能的解决方案是在应用层中建立一些确认机制。

6
如果您无法信任平台的TCP实现,请确保在应用层中构建一个确认机制。 - Kerrek SB
2
那么,确认机制是100%可靠的吗? - Bo Persson
8
没有任何协议能够做到100%的可靠性。可参考“两个将军问题”(Two Generals Problem):http://en.wikipedia.org/wiki/Two_Generals'_Problem - Barmar
仅当可靠性需要双向时才使用@Barmar。简单的确认就足以知道消息已被接收(猜测我们在这种特定情况下不必担心中间人攻击)。 - tucuxi
@tucuxi:在这种情况下,会出现假阴性(即您没有收到确认,但实际上消息已经被接收)。是否足以算作100%的可靠性取决于应用程序:通常只有一侧重新发送直到得到确认是可以的,这基本上就是TCP在底层提供其保证的方式。 - Steve Jessop
@Jessop没错,但是我之前的评论仍然是正确的:只要你收到了确认,那么消息在另一端就被正确接收了。(如果你没有收到确认,你将永远不知道发生了什么;最安全的假设是它只是消失在虚无中。) - tucuxi
3个回答

4
TCP是可靠的,因为发送的消息要么会按照相同顺序和内容被接收,假设内置校验和没有失败。但是,校验和可能会失败,因为它只有16位;要么就完全不会被接收。使用TCP,接收到的消息不应该是乱序的或者缺少中间消息。为了区分第一种情况和第二种情况,应该实现确认机制。一个好主意是发送返回传入消息的MD5或其他哈希值,这也可以确保优于CRC的消息完整性。

TCP 使用校验和,而不是循环冗余校验(CRC)。 - Barmar
@Barmar CRC是一种校验和! - Alnitak
CRC不仅仅是一个校验和,它使用位移来防止重新排序,而校验和无法检测到。 - Barmar
好的,我是指校验和。正在编辑... - tucuxi
1
@Barmar确实,CRC16等算法使用了这个概念,但是CRC实际上代表的是“循环冗余校验和”。 - Alnitak
1
不,它代表循环冗余校验(Cyclic Redundancy Check)。 - Barmar

1

您可以构建自己的应用程序,通过接收者向发送者回复成功消息,并在未收到成功消息时重新发送。

在Java中,JMS可以完成这项工作,我相信在C中也有一些现有的库可以完成同样的工作。


-2
当然TCP是可靠的协议,如果你想知道通过网络端口传输和接收的数据,请使用Wireshark软件来捕获传输和接收的数据。通过Wireshark,您可以跟踪数据包。

使用Wireshark远程方式如何帮助一个应用程序知道它的传输是否被接收?! - Alnitak
1
请看如何使用Wireshark,您可以捕获从您的计算机发出的数据包以及进入您的计算机的数据包。 - neotam
1
你没有理解重点。当然,你可以使用Wireshark来执行流量的“第三方”分析。但是你不能用它来告诉特定应用程序它自己的数据包是否已被接收。 - Alnitak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接