TCP与UDP
传输层主要功能为两台主机上的应用程序提供端到端的通信,通过端口号识别两台主机上相对应程序之间进行通信。传输层中最主要的两个协议就是 TCP 和 UDP,可以根据 IP 首部的协议字段来识别传输数据的协议类型。
TCP 是面向连接的、可靠的流协议,流是指不间断的数据结构。它的任务是把来自应用程序的数据分成合适的小块交给下面的网络层,确认接收到数据的分组。为数据块设置超时时钟,一旦超过该时间就重新发送数据。TCP 为提供可靠性传输,实行“顺序控制”或“重发控制”机制。此外还具备“流控制”、“拥塞控制”、提供网络利用率等功能。
UDP 是无连接、不可靠的数据报协议,为应用程序发送和接收数据报,只是将数据报的分组从一台主机发送到另一台主机,但并不保证数据报能够到达另一端,任何必须的可靠性都由应用程序提供。在 UDP 情况下,虽然可以确保发送消息的大小,却不能保证消息一定会达到目的端。因此,应用时会根据自己的需要进行重发处理。UDP 协议常用于分组数据较少或多播、广播通信以及视频通信等多媒体领域。
TCP用于在传输层有必要实现可靠传输的情况。
UDP主要用于那些对高速传输和实时性有较高要求的通信或广播通信。
端口号
在数据链路和网络层中,分别采用 MAC 地址和 IP 地址。前者用来识别同一链路中的不同计算机,后者用来识别 TCP/IP 网络中互连的主机和路由器。这样我们已经可以在互联网上任意两台主机上建立通信。因为同一台主机上可能有许多程序都需要用到网络,我们怎样才能确保哪些对应的程序在进行通信?在传输层中使用端口号来识别同一台计算机中进行通信的不同应用程序。因此,它也被称为程序地址。
一台计算机上同时可以运行多个程序,传输层协议采用端口号来识别本机中正在进行通信的应用程序,并准确地将数据传输。端口号由其使用的传输层协议决定,不同的传输层协议可以有相同的端口号。
仅凭目标端口识别某一个通信是远远不够的,TCP/IP 或 UDP/IP 通信中通常采用 5 个信息来识别一个通信。它们分别是“源 IP 地址”、“目的 IP 地址”、“协议号”、“源端口号”、“目标端口号”。只要其中某一项不同,则被认为是其他通信。下面是识别多个请求时采用这 5 个信息进行识别程序之间的通信:
端口号如何确定
确定端口号的方法分为两种:
1、 标准既定的端口号
这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。每个端口号都有其对应的使用目的。
例如,HTTP、TELNET、FTP等广为使用的应用协议所使用的端口号就是固定的。这些端口号也被称之为知名端口号,它们一般由0-1023的数字分配而成。除知名端口号之外,还有一些端口号也被正式注册。它们分布在1024到49151的数字之间。
2、 时序分配阀
此时,服务端有必要确定监听端口号,但是接受服务的客户端没必要确定端口号。这种方法下,客户端应用程序可以完全不用自己设置端口号,而全权交给操作系统进行分配。操作系统可以为每个应用程序分配互不冲突的端口号。动态分配的端口号取值范围在49152到65535之间。
端口号与协议
端口号由其使用的传输层协议决定。因此,不同的传输协议可以使用相同的端口号。数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。如果是TCP则传给TCP模块,如果是UDP则传给UDP模块去做端口号处理。即是是同一个端口号,由于传输协议是各自独立地运行处理,因此相互之间不会受到影响。
此外,那些知名端口号与传输层协议并无关系,只要端口一致都将分配同一程序进行处理。例如53号端口在TCP和UDP中都用于DNS服务,而80端口用于HTTP通信。
IP分片
最大传输单元(MaximumTransmission Unit,MTU)是指一种通信协议的某一层上面所能通过的最大数据包大小(以字节为单位)。数据链路层中的网络对数据帧的长度都有一个限制,不同网络的 MTU 值不同,常用的以太网为 1500 个字节。
若在 IP 层要传输的数据报大小比链路层的 MTU 还大,那么 IP 层就会对这个数据报进行分片。一个数据报会被分为若干片,每个分片的大小都小于或者等于链路层的 MTU 值。
IP 数据报分片以后,只有到达目的地才进行重新组装(这里的重新组装是达到目的地才组装,而不像其他网络协议在下一站就进行重新组装),重新组装由目的端的IP层来完成,其目的就是使分片和组装过程对传输层(TCP 和 UDP)是透明的,以及防止某些可能的性能降低。已经分片的数据报有可能会再次进行分片(即可多次分片)。
当 IP 数据报被分片后,只有第一个分片存在运输层协议首部,其余分片都不包含运输层协议的首部,但是每个分片都具有 IP 首部,并且每一片都成为一个分组,在选择路由时每一组与其他分组相互独立。由于分组之间是独立的,所以分片传输的 IP 数据报不一定按照顺序到达目的地,但是每个分片的 IP 首部能够使接收端按照正确的顺序组装这些 IP 数据报分片。
最大报文段长度(MaximumSegment Size,MSS)是 TCP 数据包每次能够传输的最大数据分段。当 TCP 报文段的长度大于 MSS 时,需要将 TCP 数据包进行分段传输。
MSS 是在 TCP 三次握手建立连接时,在两端主机之间被计算得出,会在 TCP 首部中写入 MSS 选项,告诉对方自己的接口能够适应的 MSS 的大小。为了达到最佳的传输效能 TCP 协议在建立连接时通常要协商双方的 MSS 值,然后会在两者之间选择一个较小的值来限制传输数据的大小。TCP 报文段的每个分段中都有 TCP 首部,到了端点后根据 TCP 首部的信息在传输层进行重组(即 TCP 的分段和重组都发生在传输层)。
采用 TCP 协议进行数据传输是不会造成IP 分片的,因为一旦 TCP 数据超过了 MSS,则在传输层会对 TCP 数据包进行分段,自然到了 IP 层的数据报肯定不会超过 MTU,所以就不用分片了。而对于 UDP 数据报,如果 UDP 组成的 IP 数据报长度超过了 MTU,那么 IP 数据报显然就要进行分片,因为UDP 不能像 TCP 一样自己进行分段。传输层中的 TCP 会分段,网络层中的 IP 会分片。IP 层的分片更多的是为运输层的 UDP 服务的,由于 TCP 自己会避免 IP 的分片,所以使用 TCP 传输在 IP层都不会发生分片的现象。
IP 层没有超时重传机制,所以IP 数据报的分片丢失时,必须重传整个 IP 数据报。超时和重传机制由更高层来实现(TCP 有超时重传机制,但 UDP 没有)。当来自 TCP 报文段的某一片丢失后,TCP 在超时后重发整个 TCP 报文段,该报文段对应于一份 IP 数据报。没有办法只重传数据报中的一个数据报片。
UDP
UDP 是无连接、不可靠的数据报传输层协议,为应用程序发送和接收数据报,只是将数据报的分组从一台主机发送到另一台主机,但并不保证数据报能够到达另一端,任何必须的可靠性都由应用程序提供。在 UDP 情况下,虽然可以确保发送消息的大小,却不能保证消息一定会达到目的端。没有超时和重传功能,当 UDP 数据封装到 IP 数据报传输时,如果丢失,会发送一个 ICMP 差错报文给源主机。
即使出现网络阻塞情况,UDP也无法进行流量控制。此外,传输途中即使出现丢包,UDP 也不负责重发,甚至当出现包的到达顺序杂乱也没有纠正的功能。若需要这些细节控制,则必须交给 UDP 的应用程序去处理。
UDP 首部
UDP 首部由源端口号、目标端口号、UDP 包长度以及检验和组成。UDP 首部只有 8 字节,每个部分占16 位。其结构如下图所示:
--源端口号:表示发送端的端口号,字段长度为 16 位。该字段是可选的,有时可能不会设置源端口号,没有源端口号时该字段的值设为 0。此时,可用于不需要返回的通信中;
--目标端口号:表示接收端的端口号,字段长度为 16 位;
--UDP 包长度:该字段保存了UDP 首部的长度与 UDP 数据的字节长度之和,该字段的最小值为 8 字节,IP 数据报是指数据报总的长度,因此,UDP 数据报长度是总的长度减去 IP 首部的长度;
--检验和:检验和是为了提供可靠的 UDP 首部和数据而设计;
检验和
首先先说明计算 UDP 检验和引入 UDP 伪首部的原因。上面说到, TCP/IP或 UDP/IP 通信中通常采用 5 个信息来识别一个通信。它们分别是“源 IP 地址”、“目的 IP 地址”、“协议号”、“源端口号”、“目标端口号”。只要其中某一项不同,则被认为是其他通信。然而在 UDP 首部中只有源端口号和目的端口号,余下的 3 项都包含在 IP 首部中。假如其他 3 项信息(协议号、源 IP 地址、目的 IP 地址)被破坏,可能会导致无法正确接收到所需要的包(即可能收不到需要的包,而收到不该收的包)。为了避免这类问题的出现,有必要验证一个通信中必要的 5 项识别码是否正确。因此,在检验和的计算中引入了伪首部信息,UDP 伪首部为 12 字节,它包含 IP 首部的一些字段,其目的是让 UDP 两次检查数据是否已正确到达目的地。
在 IP 首部的检验和中,只需对IP 首部进行检验,而 UDP 和 TCP 的检验和,对 UDP 首部和 UDP 数据或者 TCP 首部和 TCP 数据都进行检验。UDP 的检验和是可选的,而 TCP 的检验和是必须的。
UDP 检验和是一个端到端的检验和,它由发送端计算,然后由接收端验证。其目的是为了发现 UDP 首部和数据在发送端到接收端之间发生变化。如果 UDP 数据报的发送端没打开 UDP 校验和,而接收端计算校验和有差错,那么 UDP 数据报将会被丢掉,不产生任何差错报文。
最大 UDP 数据报长度
理论上 IP 数据报的最大长度为65535 字节,去除 20 字节的 IP 首部和 8 个字节的 UDP 首部,因此 UDP 数据报的最大长度为 65507 字节。但是,大多数实现所提供的长度比这个最大值小。由于 UDP 最大数据报的限制,大于这个限制的数据报会被截断,从而发生数据丢失,且不会有任何数据丢失的通知。一般有两个因素的限制:
应用程序可能会受到其程序接口的限制,一些 API 的实现中可能有限定 UDP 数据报的最大长度。另外,现在大部分系统都默认提供了可读写大于 8192 字节的 UDP 数据报。
受限于 TCP/IP 内核的实现,可能存在一些实现特性,使 IP 数据报长度小于 65535 字节。
UDP 优点:在少量数据的传输时,使用 UDP 协议传输信息流,可以减少TCP 连接的过程,提高工作效率;
UDP 缺点:当使用 UDP 协议传输信息流时,用户应用程序必须负责解决数据报排序,差错确认等问题;