TCP是不是保证按顺序到达?

Posted

技术标签:

【中文标题】TCP是不是保证按顺序到达?【英文标题】:Is TCP Guaranteed to arrive in order?TCP是否保证按顺序到达? 【发布时间】:2010-12-14 01:17:01 【问题描述】:

如果我发送两条TCP消息,是否需要处理后者先于前者到达的情况?还是保证按照我发送的顺序到达?我认为这不是一个特定于 Twisted 的示例,因为它应该符合 TCP 标准,但是如果任何熟悉 Twisted 的人都可以为我自己的安心提供一个特定于 Twisted 的答案,那将不胜感激:-)

【问题讨论】:

既然 TCP 不知道你的消息从哪里开始或结束,它怎么可能重新排序呢? 【参考方案1】:

只要两条消息在同一个 TCP 连接上发送,就会保持顺序。如果在同一对进程之间打开了多个连接,您可能会遇到麻烦。

关于 Twisted 或任何其他异步事件系统:我希望您会按照接收字节的顺序收到 dataReceived 消息。但是,如果您开始将工作推到延迟调用上,您可以,呃...“扭曲”您的控制流,使其无法识别。

【讨论】:

【参考方案2】:

TCP 是面向连接的,并为客户端提供按顺序 交付。当然,这适用于连接级别:各个连接是独立的。

您应该注意,通常我们指的是“TCP 流”和“UDP 消息”。

无论您使用什么客户端库(例如 Twisted),底层 TCP 连接都独立于它。 TCP 将按顺序将“协议消息”传递给您的客户端。我所说的“协议消息”当然是指您在 TCP 层使用的协议。

进一步注意,I/O 操作本质上是异步的,并且非常依赖于系统负载 + 还会增加网络延迟和损失,您不能依赖 TCP 连接之间的消息排序。

【讨论】:

你所说的between TCP 连接是什么意思?【参考方案3】:

TCP“保证”接收者将接收到重构的字节流,因为它最初是由发送者发送的。然而,在 TCP 发送/接收端点(即物理网络)之间,数据可能被无序接收、可能被分段、可能被破坏,甚至可能丢失。 TCP 使用导致错误数据包重新传输的握手机制来解决这些问题。接收器上的 TCP 堆栈将这些数据包按传输顺序放置,这样当您从 TCP 套接字读取数据时,您会收到原始发送的数据。

当你在 Twisted 中调用 doRead 方法时,数据会从套接字读取到缓冲区的大小。该数据可以表示单个消息、部分消息或多个消息。您可以从缓冲区中提取消息,但您可以保证此时字节按其传输顺序排列。

对不起,我之前的帖子弄混了水......

【讨论】:

请重新审视你的答案,因为你错了。 TCP 公开的 API 在很大程度上是一个字节顺序传递的流。您在这里指的是基础传输方法(即数据包),当然不能保证按顺序到达。 仅供参考,TCP 的“服务器层”是 IP,它当然是“无连接”的,不保证数据包顺序传递。 我对你的解释感到迷惑——在第二句中你写的数据可能被破坏(对于 TCP 客户端?),第三句你写的数据不会被破坏,因为 TCP 会处理这种情况。那么 TCP 客户端可以看到什么——数据损坏或保证正确?同样是数据的顺序,你的意思是直接连接有保证顺序,但是对于间接连接,TCP客户端可以看到数据乱序?【参考方案4】:

TCP 是一个流,UDP 是一个消息。你混淆了条款。对于 TCP,流确实会按照发送的顺序到达。 TCP 中没有不同的消息,字节在到达时出现,将它们解释为消息取决于您。

【讨论】:

回复:术语 - 是的,当然。然而,Twisted 将其抽象为不同的消息(因此将它们解释为消息并不取决于我) 值得注意的是,虽然您可能在发送方有两次写入,但在接收方可能会合并为一次读取,反之亦然 - 取决于缓冲区大小和网络条件。 不,Twisted 不会将 TCP 抽象为“消息”。您将在基本协议中获得一大块字节(在极端情况下一次减少一个字节)。 我认为从应用程序的角度来看是正确的。从协议的角度来看,TCP 本质上是一个 UDP,有很多扩展,用于连接处理、丢包重发、到达排序等。这在 Unix API 中很明显:相同的面向流的 api 调用(write、read)和面向数据包的调用(send、revc)都在这两种类型的套接字上工作。当然,您不能在子数据包级别操作 UDP“连接”,而您可以在字节流级别 TCP 连接上读取/写入。

以上是关于TCP是不是保证按顺序到达?的主要内容,如果未能解决你的问题,请参考以下文章

Django Channels 2.4 ... WebSocket 消息是不是总是按顺序到达

你真的懂接口测试基础之TCPUDP和TCP/IP协议组吗?

MFC中如何让多线程按先后顺序执行,第一个来的先执行,以后按先后到达的顺序执行

lock() 是不是保证按请求的顺序获得?

Socket.io 是不是保证按客户端顺序接收广播事件?

TCP和UDP的区别