38

TCP 是面向流的,这意味着数据作为连续的字节流传输。但令我困惑的是 TCP 创建段并将其传递给 IP。IP 创建数据包封装分段并传输它们。那么这里的连续流到底在哪里?

另一方面,UDP 是面向消息的。它从应用层接收消息,创建数据报并将其推送到 IP。到目前为止,它与 TCP 相同,而是创建并下推数据报。是什么让这个协议成为面向消息的?

4

6 回答 6

47

这些协议的用户(程序员)呈现给您的接口/API 是:

UDP

面向消息,您有一个 API(发送/接收和类似的)为您提供发送一个数据报和接收一个数据报的能力。1 次 send() 调用导致发送 1 个数据报,而 1 个 recv() 调用将准确接收 1 个数据报。

TCP

面向流,你有一个 API(send/recv 和类似的)让你能够发送或接收字节流。没有保留消息边界,TCP 可以将来自多个 send() 调用的数据捆绑到一个段中,或者它可以将来自一个 send() 调用的数据分解为多个段 - 但这对于位于 TCP 之上的应用程序是透明的,并且 recv() 只是给你返回数据,与有多少 send() 调用产生你返回的数据无关。

于 2013-07-03T11:33:14.950 回答
9

TCP 是面向流的,因为它能够以连续格式组装数据。例如,您有 1 到 4000 个字节的数据。现在它将被划分为 tcp 段,每个段都有一个序列号,比如第一个是 1-1200 字节,第二个是 1201 - 2400 等等。

它在通过 ip 数据报发送时可能会乱序传递,但后来被组装成连续的数据,从而表现为流。序列号有助于重新排序数据包。

更深入一点的解释是:

字节流由一大块数据组成,没有段或其他不规则性。对于数据报(较小的),数据块作为一个整体同时发送和接收。实际上,这意味着对于数据报,每个发送/写入调用发送一个数据包,每个读取/接收调用接收一个数据包,而对于流协议,可以以任何方式发送和接收数据。例如,发送者可以调用 send() 十次,而接收者通过一次 recv 调用接收所有数据。对于数据报,十个发送调用意味着十个数据包和十个接收调用

数据报和流

字节流

于 2013-07-03T11:20:03.017 回答
5

TCP is a connection-oriented protocol meaning it first sets up a connection to the receiver then sends the data in segments (PDU for transport layer) which is carried by IP packets. This way it's called stream because it keeps the stream of data between to ends during transfer.

UDP is a connection-less transport protocol (just like IP) with data unit called datagram. So unlike tcp, UDP transfers data without setting up a connection just sending down datagram messages to IP layer in order to be transferred.

于 2015-07-14T23:37:52.100 回答
3

这里有很多混乱。让我澄清一下。

TCP/IP是一种面向流、面向数据包和面向连接的协议。 UDP只是一个面向数据包的协议。不先建立连接。

假设您正在使用 Java 程序通过调用java.net.Socket连接到应用程序中的网络客户端的类和服务器端的 java.net.ServerSocket。一旦建立连接,数据传输就开始了。问题来了,如果我选择 TCP,数据是以流(Codata 还是无限流)或数据包形式发送的?答案是 TCP 方法接收的数据是流,但是 TCP 在发送较低的 lavel 堆栈之前将流转换为数据包。基本上,上面的应用程序层将流中的数据发送到 TCP 层,TCP 将其分解为数据包到网络层,并在从服务器(接收)端接收时执行数据包到流,因为您的应用程序 Java 只能理解溪流。首选通过 TCP 而非 UDP 传输文件,因为您无法承受丢失数据包的后果。

另一方面,UDP 是一种面向数据包的协议,其中应用程序如 Java 类 java.net.DatagramPacket;java.net.DatagramPacket;import java.net.DatagramsSocket 在与 UDP 通信之前先创建一个数据包,然后通过 UDP/IP 协议将数据包与附加信息一起发送到服务器端。请注意,当底层协议为 UDP 时,某些应用程序可能会将数据呈现为流。然而,这是在 UDP 之上的附加协议的分层,它不是 UDP 协议本身固有的东西。电视直播通常是 UDP,因为您不担心丢包。

于 2018-11-19T05:01:41.653 回答
2

TCP 的特点是这种行为对用户是透明的。应用程序。

该应用程序唯一需要做的就是调用send()并按recv()顺序发送和获取数据。

下面的层确保数据完全按照发送的顺序接收,如果丢失的数据“仍然丢失”,则会重新传输。

UDP,OTOH,将一个send()呼叫的数据保存在一起,即使它被分成几个IP数据包。这样,这些数据就可以看作一个数据报。

于 2013-07-03T11:21:05.613 回答
1

TCP 和 UDP 都是传输层协议,都提供了一个过程来处理交付(客户端到服务器),但它们在提供服务的方式上却大不相同。UDP和TCP之间的主要区别是;UDP 提供无连接服务,而 TCP 提供面向连接的服务。

这就是 TCP 可靠的原因,现在为什么我们称 TCP 为面向流的协议?

众所周知,TCP 协议会跟踪正在传输或接收的段,这就是它可靠的原因,但如果您看到 TCP 段标头,则段标头中没有段编号值字段。相反,有两个字段称为序列号和确认号。这两个字段指的是字节号而不是段号。

字节编号:TCP 对连接中传输的所有数据字节(八位字节)进行编号。编号在每个方向上都是独立的。当 TCP 从进程接收数据字节时,TCP 将它们存储在发送缓冲区中并对其编号。编号不一定从 0 开始。相反,TCP 选择 0 和 ((2)**32)− 1 之间的任意数字作为第一个字节的编号。例如,如果数字恰好是 1,057,并且要发送的总数据是 6,000 字节,则字节编号从 1,057 到 7,056。

序列号:字节编号后,TCP 为每个正在发送的段分配一个序列号。每个段的序列号是该段中承载的数据的第一个字节的编号。

假设一个 TCP 连接正在传输一个 5,000 字节的文件。第一个字节编号为 10,001。如果数据分五个段发送,每个段携带 1,000 字节,则每个段的序列号是多少?

TCP_segments

段 1 → 序列号:10,001 范围:10,001 到 11,000 段 2 → 序列号:11,001 范围:11,001 到 12,000 段 3 → 序列号:12,001 范围:12,001 到 13,000 段 4 → 序列号:13,001 范围:13,001 到 14,000 段 5 → 序列号:14,001 范围:14,001 至 15,000

这就是我们将 TCP 称为流控制协议的原因,因为它跟踪发送或接收的每个字节并确认每个段。

而为什么我们称 UDP 为面向消息的协议呢?

UDP提供无连接服务,这意味着每个用户数据报(UDP数据包)是独立的,即使它们的来源相同并且到达相同的目的地,也不会相互保持联系。无连接的后果之一是使用 UDP 的进程不能将数据流发送到 UDP 并期望 UDP 将它们分成不同的相关用户数据报(就像 TCP 一样)。相反,每个请求必须足够小以适合一个用户数据报。所以每个数据报都有边界,消息是自包含的,可以有意义。这就是为什么 UDP 也被称为面向消息的协议。

有关详细信息,请阅读 Behrouz A. Forouzan 的 TCP/IP 协议套件第 #14 和 #15 章

希望这可以帮助!

于 2019-09-23T19:04:23.683 回答