TCP是面向流的,意味着数据作为连续的字节流传输。但令我困惑的是TCP创建了段并将其传递给IP。 IP创建数据包封装段并传输它们。那么这里的连续流究竟在哪里呢?
另一方面,UDP是面向消息的。它从应用层接收消息,创建数据报并将其推送到IP。到目前为止,它与TCP相同,而是创建和推送数据报。是什么让这个协议成为一个面向消息的?答案 0 :(得分:27)
向您呈现这些协议的用户(程序员)的接口/ API是:
<强> UDP 强>
面向消息,您有一个API(发送/接收和类似),为您提供发送的能力 一个数据报,并接收一个数据报。 1发送()调用结果发送1个数据报,1个recv()调用将准确接收1个数据报。
<强> TCP 强>
面向流,您有一个API(发送/接收和类似),使您能够发送或接收字节流。没有保留消息边界,TCP可以将来自许多send()调用的数据捆绑到一个段中,或者它可以将数据从一个send()调用分解为多个段 - 但这对于位于TCP之上的应用程序是透明的,和recv()只是为你提供了数据,与你收到的数据产生的send()调用数无关。
答案 1 :(得分:4)
TCP是一种面向连接的协议,意味着它首先建立与接收器的连接,然后以IP数据包携带的段(传输层的PDU)发送数据。这种方式称为流,因为它在传输过程中将数据流保持在两端之间。
UDP是一种无连接传输协议(就像IP一样),数据单元称为数据报。因此,与tcp不同,UDP在不设置连接的情况下传输数据,只是将数据报消息发送到IP层以便传输。
答案 2 :(得分:3)
TCP是面向流的,因为它能够以连续格式组合数据。例如。你有1到4000字节的数据。现在它将分为tcp段,其中每个段将具有序列号,首先是1-1200字节,第二段是1201-2400,依此类推。
它可能在通过ip数据报发送时无序传送,但是通过显示为流而被组合成后面的连续数据。序列号有助于重新排序数据包。
更深入的解释是:
字节流由一大块数据组成,没有段或 其他违规行为。使用数据报(较小的)数据块被发送 并立即收到。在实践中,它意味着 datagrams每个send / write调用发送一个数据包,每个read / recv 呼叫接收一个数据包,而使用流协议数据可以 以任何方式发送和接收。例如。发件人可以调用send()十次, 而接收器通过一次recv调用接收所有数据。同 数据报十个发送呼叫意味着十个数据包和十个接收呼叫
答案 3 :(得分:2)
关于TCP的专长是这种行为对用户resp是透明的。应用程序。
应用程序唯一要做的就是调用send()
和recv()
以便发送和获取数据。
下面的图层确保按照发送的顺序接收数据,如果“丢失”,则重新发送丢失的数据。
UDP,OTOH,将一个send()
呼叫的数据保持在一起,即使它被分成多个IP数据包。通过这种方式,这些数据可以看作一个数据报。
答案 4 :(得分:2)
这里很混乱。让我澄清一下。
TCP / IP 是面向流,面向分组和连接的协议。 UDP 只是面向数据包的协议。不首先建立连接。
让我们说,您正在通过调用客户端上的 java.net.Socket 类和服务器上的java.net.ServerSocket使用Java程序连接到应用程序中的网络。侧。建立连接后,数据传输开始。问题来了,如果我选择了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,因为您不必担心数据包丢失。
答案 5 :(得分:0)
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字节的文件。第一个字节编号为10001。如果数据分五个段发送,每个段携带1,000个字节,那么每个段的序列号是什么?
段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章
希望这会有所帮助!