本文内容为《图解TCP/IP》一书学习笔记。本文主要概述第六章内容。
第六章 TCP与UDP
6.1 传输层的作用

传输层如何指出具体的程序?使用端口号这么一种识别码来识别在传输层上一层的应用层中所要处理的具体程序。
上面所说的需要识别的程序即应用协议。TCP/IP的应用协议大多以客户端/服务端的形式运行。其中服务端程序在UNIX系统当中叫做守护进程。例如HTTP的服务端程序是httpd(HTTP守护进程),而ssh的服务端程序是sshd(SSH守护进程)。在UNIX中并不需要将这些守护进程逐个启动,而是启动一个可以代表它们接收客户端请求的inetd(互联网守护进程)服务程序即可。它是一种超级守护进程。该超级守护进程收到客户端请求以后会创建(fork)新的进程并转换(exec)为sshd等各个守护进程。
可以通过所收到数据包的目标端口号来识别一个请求发给的是哪个服务端(守护进程)。当收到TCP的建立连接请求时,如果目标端口为22,则转给sshd,如果是80则转给httpd。然后这些守护进程会继续对该连接上的通信传输进行处理。

6.1.3 两种传输层协议TCP和UDP
TCP:面向连接的、可靠的流协议,提供可靠的通信传输。所谓流,就是指不间断的数据结构,你可以把它想象成排水管道中的水流。当应用程序采用TCP发送消息时,虽然可以保证发送的顺序,但还是犹如没有任何间隔的数据流发送给接收端。
UDP :面向无连接的,具有不可靠性的数据报协议(让广播和细节控制交给应用的通信传输)。UDP可以确保发送消息的大小,却不能保证消息的到达。
6.1.4 TCP和UDP区别
TCP用于在传输层有必要实现可靠传输的情况,由于它是面向连接并具备顺序控制、重发控制等机制的,所以它可以为应用提供可靠传输。
UDP则主要用于那些对高速传输和实时性有较高要求的通信或广播通信。
套接字Socket:在日常使用TCP或UDP时,通常会用到操作系统提供的类库,这种类库一般被称为API(Application Programming Interface,应用编程接口)。对于TCP或UDP来说会广泛使用到套接字(Socket)的API。应用程序使用套接字时,可以设置对端的IP地址、端口号,并实现数据的发送与接收。

6.2 端口号
端口号定义:类似于数据链路中的MAC地址(识别同一链路中不同计算机)与IP中的IP地址(识别TCP/IP网络中互连的主机和路由器)。传输层中的地址就是端口号,用来识别同一台计算机中进行通信的不同应用程序,也称为程序地址。

6.2.3 通过IP地址、端口号、协议号进行通信识别
仅凭目标端口号识别某一个通信是不够的。

①和②的通信是在两台计算机上进行的,它们的目标端口号相同,都是80。例如打开两个Web浏览器,同时访问两个服务器上不同的页面,就会在浏览器跟服务器之间产生类似前面的两个通信。这种情况下可以根据源端口号进行区分。
TCP/IP或UDP/IP通信中通常采用5个信息来识别一个通信。源IP、目标IP、协议号、源端口号、目标端口号。
6.2.4 端口号如何确定
- 标准既定的端口号:也叫静态方法,每个应用程序都有固定的端口号。HTTP、TELNET、FTP等广泛使用的应用协议端口号就是固定的,也被称为知名端口号,一般知名端口号在0~1023之间。
- 时序分配法:也叫动态方法,服务端有必要确定监听端口号,但客户端没必要确定端口号。客户端应用程序可以完全不用主机设置端口号,而是全权交给操作系统进行分配。操作系统可以为每个应用分配互不冲突的端口号(例如,新的端口在之前分配的号码的基础上加1)。根据这种动态分配端口号的机制,即使是同一个客户端程序发起的多个TCP连接,识别这些通信连接的5部分数字也不会全部相同。动态分配的端口号一般在49152~65535之间。
6.2.4 端口号与协议
不同的传输协议可以使用相同的端口号。例如,TCP与UDP使用同一个端口号,但使用目的不同。这是因为端口上的处理是根据每个传输协议的不同而进行的。
数据到达IP层后,会先检查IP首部中的协议号,再传给相应协议的模块,TCP传给TCP模块、UDP传给UDP模块。即使是同一端口号,传输协议之间是各自独立的处理,不会相互影响。
知名端口号与传输层协议无关系,端口一致就分配同一种程序处理。例如,53号端口在TCP与UDP中都用于DNS服务,80号端口则用于HTTP通信(目前HTTP通信必须使用TCP)。
6.3 UDP
UDP(User Datagram Protocol)不提供复杂的控制机制,利用IP提供面向无连接的通信服务。应用程序发来的数据在收到的那一刻,立即按照原样发送到网上。UDP不会负责流量控制、丢包重发、数据包的乱序纠正等。
UDP广泛应用于:
- 包量较少的通信(DNS、SNMP登)
- 视频、音频等多媒体通信(即时通信)
- 限定于LAN等特定网络中的应用通信
- 广播通信(广播、多播)
6.4 TCP
TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。
为了通过IP数据报实现可靠性传输,需要考虑很多事情,例如:数据的破坏、丢包、重复以及分片顺序混乱等问题。TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。
6.4.2 通过序列号与确认应答提供可靠性
确认应答:TCP中,发送端的数据到达接收主机时,接收端主机会返回一个已收到消息的通知,这个消息即确认应答。
TCP通过肯定的确认应答实现可靠的数据传输。当发送端将数据发出之后会等待对端的确认应答。如果有确认应答,说明数据正常到达。若没收到应答,采用超时重发来保证在丢包的情况下仍能保证数据正常到达。
未收到确认不一定意味着数据丢失,也可能是数据对方已收到,返回的确认应答在途中丢失。这种情况也会导致发送端因没有收到确认应答而认为数据没有到达目的地,从而重发。还有一些其他原因导致确认应答延迟到达。这都会导致目标主机会反复收到相同的数据。为了给上层应用提供可靠的传输,必须采用某种机制放弃重复的数据包,这种机制就是序列号。
序列号:按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号。接收端查询接收数据TCP首部中的序列号和数据的长度,将自己下一步应该接收的序号作为确认应答返送回去。


6.4.3 重发超时如何确定
重发超时定义:重发数据之前,等待确认应答到来的特定时间间隔。
TCP要求在任何网络环境下都要提供高性能特性,所以每次发包前都会计算往返时间(RTT)及其偏差(RTT时间波动的值、方差、有时也叫抖动)。重发超时的计算即要考虑往返时间也要考虑偏差,一般是比两者相加稍大的值。

数据重发之后若还是不应答,则再次发送。等待确认的时间会以2倍、4倍的指数函数增长。
数据不会无限重发。达到一定重发次数后,若还没有任何确认应答返回,会判断为网络或对端主机发生了异常,强制关闭链接。并且通知应用通信异常强行终止。
6.4.4 连接管理
TCP提供面向连接的服务。面向连接指在数据通信开始之前先做好通信两端之间的准备工作。TCP首部用于控制连接的字段被用来管理TCP连接。TCP的一个连接的建立与断开,正常过程下至少需要来回发送7个包才能完成,也就是我们常常听到的三次握手,两次挥手。

6.4.5 TCP以段为单位发送数据
建立TCP连接的同时确定了发送数据包的单位,即最大消息长度(MSS:Maximum Segment Size)。最理想情况下最大消息长度正好是IP中不会被分片处理的最大数据长度。MSS是在三次握手的时候,在两端主机之间计算得出的。两端的主机发出连接请求时,会在TCP首部写入MSS选项,告诉对方自己的接口所能适应的MSS大小。然后会在两者间选择较小的那个投入使用。

6.4.6 利用窗口控制提高速度
TCP以1个段为单位,每发一个段进行一次确认应答的处理,这样有缺点:包的往返时间越长通信性能就越低。

为了解决这个问题,TCP引入了窗口。窗口大小就是指无需等待确认应答而可以继续发送数据的最大值,确认应答不再是以每个分段,而是以更大的单位进行确认时,转发时间将会大幅度缩短。下图中,窗口大小为4个段。

如下图所示,发送数据中圈起来的部分就是窗口。发送端主机在等到确认应答返回之前,必须在缓存区中保留这部分数据。收到确认应答的情况下,将窗口滑动到确认应答中序列号的位置,这样可以顺序地将多个段同时发送提高通信性能。

6.4.7 窗口控制与重发控制
段丢失怎么办?
-
首先考虑确认应答未能返回的情况。此时不需要重发数据。在没有窗口控制的时候,没有收到确认应答的数据都会被重发。使用窗口控制后,如下图,某些确认应答丢失也无需重发。
-
再考虑报文段丢失的情况。接收主机如果收到一个自己应该接收的序号以外的数据,会针对当前为止收到的数据返回确认应答。如下图所示,某一报文段丢失后,发送端会一直收到序号为1001的确认应答。发送端主机如果连续三次收到同一个确认应答,会将对应的数据重发。这种机制比之前提到的超时管理更加高效,因此也称作高速重发机制。
6.4.8 流控制
如果在高负荷的情况下,接收端将本该接收的包丢弃的话,又触发重发机制,从而导致网络流量的无端浪费。TCP采用流控制避免这种情况发生。
流控制:发送端根据接收端的实际接收能力控制发送的数据量。
流控制具体操作:接收端主机向发送端主机通知自己可以接收数据的大小,发送端会发送不超过这个限度的数据,该限度即窗口大小。
TCP首部中,专门有一个字段来通知窗口大小。接收主机将自己可以接收的缓冲区大小放入这个字段中通知给发送端。这个字段值越大,网络吞吐量越高。下图是根据窗口大小控制流量过程的实例。

接收端收到从3001号开始的数据段后其缓冲区即满,暂时停止接收数据。之后发送端收到发送窗口更新通知后通信才得以继续进行。
6.4.8 拥塞控制
有了TCP的窗口控制,收发主机即使不再以一个数据段为单位发送确认应答,也能够连续发送大量数据包。然而,如果在通信刚开始时就发送大量数据,也可能会引发其他问题。计算机网络一般处于共享的环境,有可能因为其他主机之间的通信使得网络拥堵。网络出现拥堵时,突然发送一个较大量的数据,可能导致网络瘫痪。
为了在发送端调节所要发送数据的量,定义“拥塞窗口”。慢启动时,将这个拥塞窗口大小设置为1个数据段,之后每收到一次确认应答(ACK),拥塞窗口的值就加1。发送数据包时将拥塞窗口的大小与接收端主机通知的窗口大小做比较,按照它们中较小的那个值,发送比其还小的数据量。


TCP通信开始时,没有设置慢启动阈值。而是在超时重发时,才设置为当时拥塞窗口的一半。
由于重复确认应答而触发的高速重发与与超时重发机制的处理不同,前者要求至少3次的确认应答数据段到达对方主机后才会触发,相比后者网络的拥堵要轻。
由重复确认应答进行高速重发控制时,慢启动阈值的大小被设置为实际已发送但未收到确认应答数据量的一半,窗口的大小设置为该慢启动阈值+3个数据段的大小。
网友评论