计算机网络_05_运输层*
5.1 运输层协议概述
5.1.1 进程之间的通信
运输层的作用:提供应用进程间的逻辑通信。在IP层看来,通信的两端是两台主机。但这种说法并不够清楚,严格来讲,两台主机进行通信的本质上是两台主机的进程进行通信。从运输层的角度看,通信的真正端点是主机中的进程。也就是说,端到端的通信是应用进程之间的通信。

分用和复用:
在一台主机中通常会有多个进程同时和另一台主机通信。这意味着运输层有一个很重要的功能:复用 和 分用。
根据应用程序的不同需求,运输层需要有两种不同的运输协议,即面向连接的协议(TCP)和无连接的协议(UDP)。

5.1.2 运输层的两个主要协议
运输层主要有两个协议:
- 用户数据报协议(User Datagram Protocol, UDP) ;
- 传输控制协议(Transmission Control Protocol, TCP).
运输协议数据单元(Transport Protocol Data Unit, TPDU): 两个对等运输实体在通信时传送的数据单元叫做运输协议数据单元;
TCP传送的TPDU是TCP报文段(segment),而UDP传送的TPDU是UDP报文/用户数据报。
5.1.3 运输层的端口
端口用一个16位的端口号进行标志。
端口号只具有本地意义,即端口号只是用于标志本计算机应用层中的各进程。
在计算机中,不同计算机的相同端口号是没有意义的。
两个主机要进行通信,不仅需要知道对方的IP,还需要知道端口号。
端口的分类:
- 服务器端使用的端口号:1)熟知端口:0-1023; 2)登记端口:1024-49151.
- 客户端使用的端口号:又称为短暂端口号,数值为49152-65535,留给客户端进程选择暂时使用。
5.2 用户数据报协议UDP
5.2.1 UDP概述
UDP只在IP的数据报服务之上增加了很少一点的功能:
- 复用和分用的功能;
- 差错检测的功能。
UDP的主要特点:
- UDP是无连接的,发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延;
- UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表;
- UDP对应用层的报文不合并也不拆分,一次性交付一个完整的报文;
- UDP没有拥塞控制。
- UDP支持一对一、一对多、多对一、多对多的交互通信;
- UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
面向报文的UDP:
- 发送方UDP对应用层下发的报文既不合并、也不拆分,添加首部之后就向下交付给网络层;
- 接收方UDP在接收到网络层交上来的UDP数据报后,只去掉首部就原封不动地交付给上层的应用层。
- 应用程序必须选择合适大小的报文,若报文太长,UDP把它交给IP层后,IP层会进行分片,这会降低IP层的效率;若报文太短,就会使IP数据报的首部的相对长度太长。
5.2.2 UDP的首部格式

在计算检验和时,临时把“伪首部”和UDP用户数据报连接在一起。伪首部仅仅是为了计算校验和,UDP用户数据报下发给网络层的时候不会包含“伪首部”。
5.3 传输控制协议TCP概述
5.3.1 tcp最主要的特点
- TCP是面向连接的运输层协议;
- 每一条TCP连接都只能是点对点;
- TCP提供可靠交付的全双工通信。
- 面向字节流:“流”指的是流入或流出进程的字节序列。面向字节流是指:虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用程序下发的数据看成是一连串无结构的 字节流。TCP不保证接收方应用程序所收到的数据块和发送方应用程序发出的数据块具有同等大小的关系,但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。

TCP不关心应用层一次把多长的报文发送到TCP缓存,它会对连续的字节流进行分段,形成TCP报文段。TCP根据对方给出的 窗口值 和 当前网络拥塞 的程度来决定一个报文应包含的字节数。
5.3.2 TCP的连接
- TCP连接的端点不是主机,也不是主机的IP地址,不是应用进程,也不是运输层的协议端口。而是 套接字(socket)。端口号拼接到IP地址,即构成了所谓的套接字。
问题:为什么网络层会知道目的IP地址和源IP地址?
TCP与IP直接打交道,调用IP发送函数 IP_Send(Destination_IP, Source_IP, TCP报文)将目的IP地址发送给网络层,让网络层知道目的IP是哪个。
5.4 可靠传输的工作原理
5.4.1 停止等待协议
“停止等待”就是发送方每发送一个分组就停止发送,等待对方的确认。在收到对方的确认后,再继续发送下一个分组。
- 无差错情况: 发方A发送分组M1,发送完就暂停发送,等待B的确认(ACK)。B收到了M1向A发送ACK。A在收到了对M1的确认后,就再发送下一个分组M2。这样持续下去。
- 出现差错:
- 在B会出现两种情况: 1) B接收M1出现差错,就丢弃M1,其他什么也不做;2)M1在传输过程中丢失,B也什么都不做。解决办法是A超时重传。A为每个发送的分组都设置一个超时计时器,超时之前收到了确认超时会被撤销,若超时就重传。
- 在A会出现两种情况:1)B发送出对M1的确认后,确认丢失了,解决办法是A超时重传;2)B发出对M1的确认后,A迟迟没有收到确认,此时也会超时重发。
需要注意的是:
- 在发送完一个分组后,必须暂时保留该分组的副本,以备重发;
- 分组和确认分组都必须进行编号;
- 超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。
停止等待协议的缺点:
停止等待协议的优点是简单,缺点是信道利用率太低。

为了提升信道利用率,流水线传输是更好的方式。流水线传输是指发送方不断发送分组,接收方接受到分组就马上回传确认分组。

5.4.2 连续ARQ协议

累积确认:
接收方一般采用 累积确认 的方式,即只确认收到的不间断分组的最后一个分组,例如:收到了 1 2 3,只确认3。
Go-back-N(回退N):
- 如果发送方发送了前5个分组,而中间的第3个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,所以只好把后面的三个分组重传一次。这就叫做回退N,表示需要再退回来重传已经发送过的N个分组。
- 由此可见,当通信线路质量不好时,连续ARQ协议会带来负面影响。
TCP可靠通信的具体实现:
- TCP连接的两端都必须有窗口:发送方有发送窗口,接收方有接收窗口。接收窗口满了且所有分组序号连续时,这些分组就被统一上传给上层;
- TCP的可靠传输机制由 字节的序号 进行保证;
- TCP的所有确认都是基于序号而不是基于报文段;
- TCP两端的四个窗口经常处于动态变化中;
- TCP连接的往返时间也不是固定的,因此需要使用特定的算法估算较为合理的重传时间。
5.5 TCP报文段的首部格式
- TCP虽然是面向字节流的,但是TCP传送的数据单元却是报文段;
- 一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它首部各字段的作用;
- TCP报文段首部的前20个字节是固定的,后面有4n字节是根据需要而增加的选项(n是整数)。因此TCP首部的最小长度是20字节。
TCP报文段的首部示意图:

- 第一个4字节:源端口(2字节)+目的端口(2字节);
- 第二个4字节:序号(表示本报文段数据部分的首字节在字节流中的编号);
- 第三个4字节:确认号(表示期望收到的下一个报文段数据部分的首字节在字节流中的编号);
- 第四个4字节:数据偏移(4 bit,即首部长度,该值*4表示首部占的字节数)+保留(6 bit,保留为以后使用)+URG(1 bit,当URG=1表明该紧急指针字段有效,它告诉系统此报文段中有紧急数据,需要高优先级传送)+ACK(1 bit,只有当ACK=1时确认字段才有效)+PSH(1 bit,)+PSH(push, 1 bit, 当PSH=1时,传输层一收到该报文,就很快地交付给应用层,而不再等到缓存都填满了再上交)+RST(reset,1 bit,当RST=1,表明TCP连接出现主机崩溃等差错,必须释放连接,然后再重新建立连接)+SYN(1 bit,同步位SYN=1表示这是一个连接请求报文或连接接收报文,当连接建立后SYN=0)+FIN(1 bit,用来释放一个连接,FIN=1表示此报文的发送端的数据已经发送完毕,要求释放连接)+窗口(16 bit,用以指明本主机的接收窗口大小)。
- 第五个4字节:检验和(2字节,检验和字段检验的范围包括首部和数据两个部分。在计算检验和时,要在首部中加入包含IP地址的伪首部)+紧急指针(2字节,告诉系统在本数据报的数据部分有多少字节是紧急数据,紧急数据放在数据部分的最前面)。
- 可选字段:
5.6 TCP可靠传输的实现
5.6.1 以字节为单位的滑动窗口
根据接收方给出的接收窗口大小,发送方构造自己的发送窗口。
发送窗口表示:在没有收到接收方的确认的情况下,发送方可以连续把窗口内的数据都发送出去。发送窗口里面的序号表示允许发送的序号。
显然,窗口越大,发送方就可以在收到接收方确认之前连续发送更多的数据,因而可获得更高的传输效率。
接收窗口表示:在本窗口没有被连续序号的字节填满之前,不会将窗口里的数据上交。
需要注意三点:
- 发送方的发送窗口并不总和接收方的接收窗口一样大,因为有一定的时间滞后;
- TCP标准没有规定对不按序到达的数据如何处理。通常是先临时放在接受窗口中,等到字节流中所缺失的字节收到后,再按序交付给上层的应用进程;
- TCP要求接收方必须有累积确认功能,这样可以减少传输开销。
接收方发送确认:
- 接收方可以在合适的时候发送确认,也可以在自己有数据要发送的时候把确认信息顺便捎带上。
- 实际上捎带确认并不经常发生,同时接收方也不应过分推迟发送确认。
5.6.2 超时重传时间的选择
- 如果把超时重传时间设置的太长或太短,都会带来负面影响。TCP设置了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间差就是报文段的往返时间RTT。
5.6.3 选择确认SACK
问题:如果收到的报文段无差错,只是未按序号,中间还缺少几个序号的数据,那么能否设法只重传缺少的数据而不重传已经正确到达接收方的数据?
答案是可以的,选择确认(selective ACK, SACK)就是一种可行的处理方法。
5.7 TCP的流量控制
5.7.1 利用滑动窗口实现流量控制
- 一般来说,我们总希望数据传输的快一些,但如果发送方把数据发送的过快,接收方来不及接收,这就会造成数据的丢失;
- 流量控制(flow control)就是让发送方的发送速率适中,既要让接收方来得及接收,也不要使网络拥塞;
- 利用滑动窗口机制可以很方便地在TCP连接上实现流量控制。
当TCP创建连接的时候,接收方会告诉对方自己的接受窗口的容量。在数据收发的过程中,接收方的接收窗口可能会因为某些原因没有及时将数据上交,导致接收窗口满了,这样接收方发送的确认中的窗口长度就是0。发送方接受到这个确认之后,发现接收窗口长度为0,发送方就不会再发数据报了。为了解决这个问题,TCP为每个连接设置了一个 持续计时器(persistence timer),只要TCP连接的一方收到了对方的零窗口通知,就启动该计时器。若计时器的时间到期,就发送一个零窗口探测报文段,对方在确认这个报文段的时候会给出最新的接收窗口长度。若最新的接收窗口长度仍然为0,则持续计时器将被重置。若最新的接收窗口值不是0了,则僵局就被打破了。
5.7.2 TCP的传输效率
可以用不同的机制来控制TCP报文段的发送时机:
- 第一种机制是最大发送机制:当缓存中存放的数据字节数达到了最大报文段长度MSS,就组成一个报文段发出去;
- 第二种机制是由发送方的应用进程指明要求发送报文段,即TCP支持的推送操作;
- 第三种机制是发送方的一个计时器时限到了,这是就把缓存中已有的缓存数据装入报文段发送出去。
5.8 TCP的拥塞控制
5.8.1 拥塞控制的一般原理
- 在某段时间内,对网络中某资源的需求超过了该资源所能提供的范围之外,网络的性能就会下降,这种现象称为 拥塞。
- 拥塞控制 就是防止过多的数据注入到网络中,使网络中的路由器或链路不至于过载。
- 拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负载。
- 拥塞控制和流量控制的区别:拥塞控制既要考虑接收端的接收能力,也要考虑收发路径中各个转发节点的负载能力,而流量控制只考虑前者。
5.8.2 TCP的拥塞控制方法
- TCP采用基于窗口的方法进行拥塞控制。该方法属于闭环控制方法。
- TCP发送方维持一个拥塞窗口 CWND(Congestion window):
- 拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化;
- 发送端利用拥塞窗口,根据网络的拥塞程度调整发送的数据量;
- 所以,发送窗口的大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞状况,所以真正的发送窗口值为: min(接收方的接收窗口值,拥塞窗口值)
拥塞的判断:
- 重传定时器超时:通信线路的传输质量一般都很好,因传输出错而丢弃分组的概率是很小的,因此只要出现了超时,就可以猜想网络出现了拥塞;
- 收到三个相同(重复)的ACK:个别报文段会在网络中丢失(例如第2分组丢失,发方一直收到第1的确认,发送了第3分组,收到第1的确认,发送第4分组,收到第1的确认),预示着可能出现拥塞,因此应该尽快采取控制措施,避免拥塞。
4种典型的拥塞控制算法:
1)慢开始(slow start):由小到大逐渐增大拥塞窗口数值,每次的增加量 = Min(收到的确认报文段所确认的字节数,MSS);
....
5.8.3 主动队列管理AQM
AQM实际就是对路由器中的分组排队队列进行智能管理,而不是简单地把队列的尾部丢掉。

5.9 TCP的运输连接管理
5.9.1 TCP的连接建立
TCP是面向连接的协议。运输连接有三个阶段:
- 连接建立
- 数据传送
- 连接释放
运输连接的管理就是使得运输连接的建立和释放都能正常地进行。
TCP连接建立的过程中要解决的三个问题:
- 要使双方能够确知对方的存在;
- 要允许双方协商一些数据(如最大窗口值、是否使用窗口扩大选项等);
- 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
客户-服务器方式:
- TCP连接的建立采用客户服务器方式;
- 主动发起连接的应用进程叫 客户(client);
- 被动等待连接的应用进程叫 服务器(server).
TCP连接的建立:
- TCP建立连接的过程俗称“握手”;
- 握手需要在客户和服务器之间交换三个TCP报文段。这称之为三报文握手:
- 第一次握手,客户端->服务器端:SYN = 1, seq = x. 第一次握手中,请求报文段的首部中,序号seq=x表明数据部分的第一个数据字节的序号是x,x不一定是1,由系统决定,同步位SYN=1表明这是一个连接请求。第一次握手后客户端进入SYN_SEND状态;
- 第二次握手,服务器端->客户端:SYN = 1,ACK = 1,seq=y,ack=x+1. 第二次握手中,服务器端在确认报文段中使SYN=1,表明这是一个连接报文段,ACK=1表明这是一个确认报文段,确认号ack = x+1,自己选择的序号seq = y,y自己定义。第二次握手完成后,服务器端由LISTEN状态进入SYN_RECV状态;
- 第三次握手,客户端->服务器端:ACK = 1,seq = x+1,ack = y+1. 第三次握手中,客户端在数据报首部中令ACK=1,表明这是一个确认报文段,同时ack = y+1表明第二次握手发送的报文客户端已经接受到了,seq = x+1表示响应第二次握手对序号为x+1的字节的请求。第三次握手完成后,客户端和服务器端都进入ESTABLISHED状态,客户端通知上层应用进程:连接已经建立。
5.9.2 TCP的连接释放
TCP连接的释放采用四报文挥手:
- 第一次挥手,(假设客户端先发送完数据)客户端->服务器端:FIN = 1, seq = u. FIN=1表示这是一个连接关闭请求,seq=u表示报文的序号。第一次挥手完成后客户端进入FIN_WAIT1状态;
- 第二次挥手,服务器端->客户端:ACK=1,ack=u+1,seq=v. ACK=1表示这是一个确认报文段,ack=u+1表示第一次挥手发送的报文我服务器端收到了,seq=v标识服务器端发送的报文的序号。第二次挥手完成后,服务器端进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态,从客户端到服务器端的这个连接就释放了,TCP连接处于半关闭状态,服务器端的接收缓冲区关闭,接收不到数据了;
- 服务器端未发送的数据继续发送......,客户端只单纯发送确认报文段,不包含数据。
- 第三次挥手(此时服务器端发送最后一个数据报),服务器端->客户端:FIN=1,ACK=1,seq=w,ack=u+1.第三次挥手完成后服务器端进入LAST_ACK状态;
- 第四次挥手,客户端->服务器端:ACK=1,seq=u+1,ack=w+1.第四次挥手完成后客户端进入TIME_WAIT状态 ,服务器端接受到第四次挥手后关闭。客户端在2MSL时间内若未接收到服务器端发送的第三次挥手请求就关闭。
为什么客户端需要有一个TIME_WAIT状态而不是直接关闭?
1)为了提高客户端发送的最后一个ACK报文段到达服务器端的概率。在2MSL(Maxium Segment Lifetime,数据报最大生存时间)内,如果客户端都没有收到服务器端重传的FIN报文,那么就可以认为服务器端已经收到了客户端发送的ACK报文,客户端可以进入关闭状态;
2)为了防止“已经失效的连接请求报文段”出现在本连接中。客户端在发送完最后一个ACK报文后,经过2MSL,就可以使得本连接持续时间内所产生的所有报文段都消失,在2MSL时间内,该地址上的连接(客户端地址,端口和服务器的端口地址)不能被使用,比如我们在建立一个连接后关闭连接然后迅速重启连接,那么就会出现端口不可用的情况。
5.9.3 TCP的有限状态机

浙公网安备 33010602011771号