TCP与UDP

Apr 27 2016 Network

前言

TCP/IP中有两个具有代表性的传输层协议,它们分别是TCP和UDP。TCP提供可靠的通信传输,而UDP则常被用于让广播和细节控制交给应用的通信传输。所以,根据通信的具体特征,选择何时的传输层协议是非常重要的。

传输层的作用

我们知道IP首部中有一个协议字段,用来标识网络层(IP)的上一层所采用的哪一种传输层协议。根据这个协议号,就可以识别IP传输的数据是TCP的内容还是UDP的内容。同样,传输层为了识别所传输的数据究竟应该发给哪个应用,也设定了这样的一个编号——端口号。比如httpd的端口号为80,sshd的端口号为22。

因此,传输协议TCP、UDP的作用就是通过接收数据中的目标端口号识别目标处理程序,然后将数据传给诸如HTTP、TELNET以及FTP等应用层协议进行处理。

端口号

数据链路层用MAC地址识别同一链路中的不同计算机、IP层用IP地址识别TCP/IP网络中互联的主机和路由器,而传输层用的是端口号。端口号用于识别同一台计算机中进行通信的不同应用程序,也称程序地址。如下图所示:

根据端口号识别应用

通过IP地址、端口号、协议号进行通信识别

仅凭目标端口识别某一个通信是远远不够的。

TCP/IP或UDP/IP通信中通常采用5个信息来识别一个通信。它们是”源IP地址“、”目标IP地址“、”协议号“、”源端口号“、”目标端口号“。只要其中某一项不同,则被认为是其他通信。

端口号如何确定

除知名端口号外,还有一些端口号也被正是注册,它们分布在1024~49151的数字之间。不过,这些端口号可用于任何通信用途。

根据这种动态分配端口号的机制,即使是在同一个客户端程序发起的多个TCP连接,也不会发送冲突。动态分配的端口号取值范围在49152~65535之间。

端口号与协议

不同的传输协议可以使用相同的端口号。数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块。如果是TCP则传给TCP模块、如果是UDP则传给UDP模块去做端口号的处理。

此外,那些知名端口号与传输层协议并无关系,只要端口一致都将分配同一种程序进行处理。例如,53端口号在TCP与UDP中都用于DNS服务,而80端口号用于HTTP通信。

UDP

UDP是User Datagram Protocol的缩写。

UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。

及时是出现网络拥堵的情况下,UDP也无法进行流量控制等避免网络拥塞的行为。此外,传输途中即使出现丢包,UDP也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。如果需要这些细节控制,那么不得不交由采用UDP的应用程序去处理。

由于UDP面向无连接,它可以随时发送数据。再加上UDP本身的处理既简单又高效,因此经常用于以下几个方面:

TCP

TCP实现了对数据传输时各种控制功能,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。根据TCP的这些机制,在IP这种无连接的网络上也能够实现高可靠性的通信。

TCP的特点及其目的

为了通过IP数据报实现可靠性传输,需要考虑很多事情,例如数据的破坏、丢包、重复以及分片顺序混乱等问题。如不能解决这些问题,也就无从谈起可靠传输。

TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

通过序列号与确认应答提高可靠性

在TCP中,当发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知。这个消息叫做确认应答(ACK)。如下图所示:

正常的数据传输

如果有确认应答,说明数据已经成功达到对端。反之,则数据丢失的可能性很大。如下图所示:

数据包丢失的情况

未收到确认应答并不意味着数据一定丢失。也有可能是数据对方已经收到,只是返回的确认应答在图中丢失。这种情况也会导致发送端因没有收到确认应答而认为数据没有达到目的地,从而进行重新发送。如下图所示:

确认应答丢失的情况

TCP是通过序列号机制实现确认应答处理、重发控制以及重复控制等功能的。序列号是按顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接收的序号作为确认应答返回。就这样,通过序列号和确认应答号,TCP可以实现可靠传输。如下图所示:

发送的数据

重发超时如何确定

重发超时是指在重发数据之前,等待确认应答到来的哪个特定时间间隔。如果超过了这个时间仍未收到确认应答,发送端将进行数据重发。那么这个重发超时的具体时间长度是如何确定的?

最理想的是,找到一个最小时间,它能保证”确认应答一定能在这个时间内返回“。然而这个时间长短随着数据包途径的网络环境的不同而有所变化。即使是在同一个网络中,根据不同时间的网络拥堵程度时间的长短也会发生变化。

为此,TCP在每次发包时都会计算往返时间及其偏差。将这个往返时间和偏差相加,重发超时的时间就是碧这个总和要稍大一点的值。在BSD的Unix以及Windows系统中,超时都以0.5秒为单位进行控制,因此重发超时都是0.5秒的整数倍。不过,由于最初的数据包还不知道往返时间,所以其重发超时一般设置为6秒左右。

连接管理

TCP提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好通信两端之间的准备工作。通过TCP首部用于控制的字段来管理TCP连接,一个连接的建立与断开,正常过程至少需要来回发送7个包才能完成。如下图所示:

TCP连接的建立与断开

TCP以段为单位发送数据

在建立TCP连接的同时,也可以确定发送数据包的单位,我们也可以称其为”最大消息长度“(MSS:Maximun Segment Size)。最理想的情况是,最大消息长度正好是IP中不会被分片处理的最大数据长度。

TCP在传送大量数据时,是以MSS的大小将数据进行分割发送。进行重发时,也是以MSS为单位。

MSS是在三次握手的时候,在两端主机之间被计算得出。两端的主机在发出建立连接的请求时,会在TCP首部中写入MSS选项,告诉对方自己的接口能够适应的MSS大小。然后会在两者之间选择一个较少的值投入使用。

利用窗口控制提高速度

TCP以1个段为单位,每发一个段进行一次确认应答处理,如下图。这样的传输方式有一个缺点。那就是,包的往返时间越长通信性能就越低。

按数据包进行确认应答

为了解决这个问题,TCP引入了窗口概念。如下图,确认应答不再是以每个分段,而是更大的单位进行确认时,转发时间将会被大幅度的缩短。即发送端主机在发送了一个段以后不必要一直等待确认应答,而是继续发送。

用滑动窗口方式并行处理

窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。上图中,窗口大小为4个段。

这个机制实现了使用大量的缓冲区,通过对多个段同时进行确认应答的功能。如果窗口中的数据有丢失,就必须重发,如果收到确认应答,则将窗口滑动到确认应答的序列号的位置。所以,这种机制也被称为滑动窗口控制。如下图所示:

滑动窗口方式

窗口控制与重发控制

在使用窗口控制中,如果出现段丢失该怎么办?

首先,我们考虑确认应答未能返回的情况。在没有使用窗口控制的时候,没有收到确认应答的数据都会被重发。而使用了窗口控制,某些确认应答即便丢失也无需重发。如下图:

没有确认应答也不受影响

其次,我们来考虑一下某个报文段丢失的情况。如下图所示,接收主机如果收到一个自己应该接收的序号以外的数据时,会针对当前为止收到数据返回确认应答。发送端知己如果连续3次收到同一个确认应答,就会将其所对应的数据进行重发。这种机制比之前的超时管理更加高效,因此也被称作高速重发机制。

高速重发控制

流控制

为防止网络流量无端浪费,TCP提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量。具体操作是,接收端主机向发送端主机通知自己可以接收数据的大小,于是发送端会发送不超过这个限度的数据。该大小限度就被称作窗口大小。在前面介绍的窗口大小的值就是由接收端主机决定的。

在TCP首部中,专门有一个字段用来通知窗口大小。如果接收端的这个缓冲区数据溢出,窗口大小的值也会随之被设置为一个更小的值通知发送端。如果缓冲区满了,就暂时停止接收数据,发送端可以时不时发送窗口探测,获取最新的窗口大小。

拥塞控制

如果窗口比较大,一开始大家都发送大量数据包,就可能造成拥塞。TCP为了防止这个问题的出现,在通信开始的时候会通过慢启动算法得出数值,对发送数据量进行控制。

为了在发送端调节索要发送的数据量,定义了一个叫做“拥塞窗口”的概念。慢启动时,将拥塞窗口设置为1个数据段(1MSS),之后没收到一个确认应答,拥塞窗口的值就加1或者按其它方式增大。当然不会无线增加,关于这个拥塞窗口的控制由于篇幅就不继续展开了。

总结

这篇文章主要是介绍了传输层TCP和UDP协议,重点是对TCP协议展开了分析,包括序列号、确认应答、重发超时、连接管理、窗口控制、流控制和拥塞控制等。能理解上面的那些示意图,应该就掌握了个大概了,我想这也是《图解TCP/IP》一书的优势吧,可缺点应该就是还不够深入,如果需要深入学习的话还是需要看《TCP/IP详解》。

Network