1- 运输层概述
1.1 基本概念
1.2 进程之间的通信
- 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。
- 当网络的边缘部分中的两个主机使用网络的核心部分的功能进行端到端的通信时,只有位于网络边缘部分的主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到三层(到网络层)的功能。
1.3 进程之间通信流程
局域网1上的主机与局域网2上的主机,通过互连的广域网进行通信,网络层的作用范围是主机到主机。
提供直接的通信服务是运输层的任务。运输层协议又称为端到端协议,运输层的作用范围是应用进程到应用进程也称为端到端。
步骤分析
“逻辑通信”是指运输层之间的通信好像是沿水平方向传送数据,但事实上,这两条数据并没有一条水平方向的物理连接,要传送的数据是沿着图中上下多次的虚线方向传送的。
进程Ap1与Ap4之间进行基于网络的通信,进程Ap2与Ap3之间进行基于网络的通信,在运输层使用不同的端口,来对应不同的应用进程,然后通过网络层及其下层来传输应用层报文。
接收方的运输层通过不同的端口,将收到的应用层报文,交付给应用层中相应的应用进程,这里端口并不是指看得见、摸得着的物理端口,而是指用来区分不同应用进程的标识符。
1.4 概念总结
2- 运输层端口号、复用与分用
2.1 为啥使用端口号
2.2 发送方的复用和接收方的分用
UDP复用
这是收发双方的应用进程,发送方的某些应用进程所发送的不同应用报文,在运输层使用UDP协议进行封装,这称为UDP复用。
TCP复用
另一些应用进程所发送的不同应用报文,在运输层使用TCP协议进行封装,这称为TCP复用。
IP复用
运输层使用端口号来区分不同的应用进程,不管是使用运输层的UDP协议封装成的UDP用户数据报,还是使用TCP协议封装成的TCP报文段,在网络层都需要使用IP协议封装成IP数据报
发送方
IP数据报首部中的协议字段的值,用来表明IP数据报的数据载荷部分,封装的是何种协议数据单元,取值为6。表示封装的是TCP报文段,取值为17,表示封装的是UDP用户数据报。
接收方
接收方的网络层收到IP数据报后进行IP分用,若IP数据报首部中协议字段的值为17,则把IP数据报的数据的数据载荷部分所封装的UDP用户数据报,上交运输层的UDP。若协议字段的值为6,则把IP数据报的数据载荷部分所封装的TCP报文段,上交运输层的TCP。运输层对UDP用户数据报进行UDP分用,对TCP报文段进行TCP分用,也就是根据端口号,将它们交付给上层相应的应用进程。
2.3 运输层熟知端口号
不管在运输层使用UDP还是TCP协议,在网络层都需要使用IP协议,IP数据报首部中协议字段的值,表明了IP数据报数据载荷部分,封装的是何种协议数据单元。
3- 运输层传输流程
3.1 步骤一
通过实例来说明运输层端口号的作用
用户PC、DNS服务器、WEB服务器通过交换机进行互联,它们处于同一个以太网中。DNS服务器中的记录有该域名所对应的IP地址。我们在用户PC中使用网页浏览器来访问Web服务器的内容,在网页浏览器的地址栏中输入Web服务器的域名。用户PC中的DNS客户端进程会发送一个DNS查询请求报文,其内容为"域名www.porttest.com所对应的IP地址是什么?"
DNS查询请求报文需要使用运输层的UDP协议,封装成UDP用户数据报,其首部中的源端口字段的值,在短暂端口号(49151~65535)中挑选一个未被占用的,用来表示DNS客户端进程,例如49152。目的端口字段的值设置为53,这是DNS服务端进程所使用的熟知端口号。
3.2 步骤二
将UDP用户数据报封装在IP数据报中,通过以太网发送给DNS服务器,DNS服务器收到该数据报后。
3.3 步骤三
从中解封出UDP用户数据报,UDP首部中的目的端口号为53,这表明应将该UDP用户数据报的数据载荷部分,也就是DNS查找请求报文交付给本服务器中的DNS服务器端进程,DNS服务器端进程解析DNS查询请求报文的内容,然后按其要求查找对应的IP地址。
之后,会给用户PC发送DNS响应报文,其内容为"域名www.porttest.comsu所对应的IP地址是192.168.0.3"。DNS响应报文需要使用运输层的UDP协议,封装成UDP用户数据报,其首部中的源端口字段的值设置为熟知端口号53,表明这是DNS服务器端进程所发送的UDP用户数据报,目的端口字段的值设置为49152,这是之前用户PC中发送DNS查询请求报文的DNS客户端进程所使用的短暂端口号。之后,将UDP用户数据报封装在IP数据报中的通过以太网发送给用户PC。
3.4 步骤四
之后,将UDP用户数据报封装在IP数据报中通过以太网发送给用户PC。用户PC收到该数据报后,从中解封出UDP用户数据报。UDP首部中的目的端口号为49152,这表明应将该UDP用户数据报的数据载荷部分也就是DNS响应报文,交付给用户PC中的DNS客户端进程。DNS客户端进程解析DNS响应报文的内容,就可知道自己之前的所请求的Web服务器的域名,所对应的IP地址为192.168.0.3。
3.5 步骤五
现在,用户PC中的HTTP客户端进程,可以向Web服务器发送HTTP请求报文,其内容为"首页内容是什么?"HTTP请求报文需要使用运输层的TCP协议封装成TCP报文段,其首部中的源端口字段的值,在短暂端口号49151~65535中挑选一个未被占用的,用来表示HTTP客户端进程,例如仍然使用之前用过的49152。目的端口字段的值设置为80,这是HTTP服务器进程所使用的熟知端口号。
3.6 步骤六
之后,将TCP报文段封装在IP数据报中,通过以太网发送给Web服务器。Web服务器收到该数据报后,从中解封出TCP报文段。TCP首部中的目的端口号为80,这表明应该将TCP报文段的数据载荷部分也就是HTTP请求报文,交付给本服务器中的HTTP服务器端进程,HTTP服务器端进程解析HTTP请求报文的内容,然后按其要求查找首页内容。
3.7 步骤六
之后,会给用户PC发送HTTP响应报文,其内容是HTTP客户端所请求的首页内容,HTTP响应报文需要使用运输层的TCP协议封装成TCP报文段,其首部中的源端字段的值设置为熟知端口号80。表明这是HTTP服务器端进程所发送的TCP报文段,目的端口字段的值设置为49152,这是之前用户PC中,发送HTTP请求报文HTTP客户端进程所使用的短暂端口号。
3.8 步骤七
之后,将TCP报文段封装在IP数据报中,通过以太网发送给用户PC,用户PC收到该数据报后,从中解封出TCP报文段。TCP首部中的目的端口号为49152,这表明应将该TCP报文段的数据载荷部分,也就是HTTP响应报文,交付给用户PC中的HTTP客户端进程。
HTTP客户端进程解析HTTP响应报文的内容,并在网页浏览器中进行显示,这样我们就可以在网页浏览器中,看到Web服务器所提供的首页内容。
4-UDP和TCP的对比
4.1基本概念
- UDP 和 TCP是TCP/IP体系结构运输层中的两个重要协议。
- 当运输层采用面向连接的 TCP协议时,尽管下面的网络是不可靠的,但这种逻辑通信信道就相当于一条全双工的可靠信道。
- 当运输层采用无连接的 UDP协议时,这种逻辑通信信道是一条不可靠信道。
两个对等运输实体在通信时传送的数据单位叫作运输协议数据单元 TPDU。
TCP 传送的数据单位协议是 TCP 报文段,UDP 传送的数据单位协议是 UDP 报文或用户数据报。
UDP特点
无连接的协议,提供无连接服务。其传送的运输协议数据单元TPDU是UDP报文或者用户数据报。
支持单播,多播、广播,不提供可靠交付。简单适用于很多应用,如多媒体应用等。
UDP的通信是无连接的,不需要套接字(Socket)。
TCP特点
面向连接的协议,提供面向连接服务。其传送的运输协议数据单元TPDU是TCP报文。
支持点对点单播,不支持多播、广播、提供可靠服务。
复制、用于大多数应用,如:万维网、电子邮件、文件传送等。
TCP是面向连接的,TCP之间的通信必须要在两个套接字(Socket)之间建立连接。
两者对比
使用UDP协议的通信双方,可以随时发送数据。使用TCP协议的通信双方,在进行数据传输之前必须使用“三报文握手”来建立TCP连接。
TCP连接建立成功后才能进行数据传输,数据传输接收后,必须使用"四报文挥手",来释放TCP连接。
4.2 用户数据报协议UDP
4.2.1 基本传输
可以发送广播
可以向某个多播组发送多播
还可以发送单播
总结
使用UDP协议进行通信的四台主机,其中任何一台主机都可向其他三台主机发送广播。也可以向某个多播组发多播,还可以向某台主机发送单播。
UDP支持单播、多播、以及广播。UDP支持一对一,一对多,以及一对全的通信。
4.2.2 对应用报文的处理
步骤流程
发送方的应用进程,将应用层报文交付给运输层的UDP。UDP直接给应用层报文添加一个UDP首部,使之成为UDP用户数据报,然后进行发送。
接收方的UDP收到该UDP用户数据报后,去掉UDP首部,将应用层报文交付给应用进程。也就是说,UDP对应用进程交下来的报文既不合并也不拆分,而是保留这些报文的边界,换句话来说。UDP是面向应用报文的。
4.2.3 UDP向上层提供无连接不可靠传输服务
网际层向其上层提供的是无连接不可靠的传输服务,当运输层使用UDP协议时,向其上层提供的也是无连接不可靠的传输服务。
流程步骤
发送方给接收方发送UDP用户数据报,若传输过程中用户数据报受到干扰而产生误码,接收方UDP可以通过该数据报首部中的检验和字段的值,检查出产生误码的情况。但是仅仅丢弃该数据报,其他什么也不做,发送方给接收方发送UDP用户数据报。
如果该数据报被因特网中的某个路由器丢弃了,发送方UDP不做任何处理。因为UDP向上层提供的是无连接不可靠的传输服务。对于UDP用户数据报出现的误码和丢失等问题,UDP并不关心。基于UDP的这个特点,UDP适用于实时应用,例如IP电话,视频会议等。
4.3 传输控制协议TCP
4.3.1 基本传输
使用TCP协议的通信双方,在进行数据传输之前,必须使用“三报文握手”建立TCP连接。
TCP连接建立成功后,通信双方之间就好像有一条可靠的通信信道,通信双方使用这条基于TCP连接的可靠信道进行通信。
总结
很显然,TCP仅支持单播,也就是一对一的通信。
4.3.2 对应用报文的处理
运输过程
发送方
- TCP会把应用进程交付下来的数据块看作是一连串无结构的字节流,TCP并不知道这些待传送的字节流的含义。
- 并将他们编号,并存储在自己发送缓存中。
- TCP会根据发送策略,提取一定量的字节构建TCP报文并发送。
接收方
- 一方面从所接受到的TCP报文段中,取出数据载荷部分并存储在接收缓存中;一方面将接收缓存中的一些字节交付给应用进程。
- TCP不保证接收方应用进程所收到的数据块与发送方发送的数据块,具有对应大小的关系(例如,发送方应用进程交给发送方的TCP共10个数据块,但接收方的TCP可能只用了4个数据块,就把收到的字节流交付给了上层的应用进程,但接收方收到的字节流必须和发送方应用进程发出的字节流完全一样)。
- 接收方的应用进程必须有能力识别收到的字节流,把它还原成有意义的应用层数据。
TCP是面向字节流的,这正是TCP实现可靠传输、流量控制、以及拥塞控制的基础。在实际网络中,基于TCP连接的两端,可以同时进行TCP报文段的发送和接收,也就是全双工通信。
4.3.3 TCP向上层提供面向连接的可靠传输服务
尽管网际层中的IP协议,向上层提供的是无连接不可靠的传输服务。也就是说,IP数据报可能在传输过程中出现丢失或误码。
但只要运输层使用TCP协议,就可向其上层提供面向连接的可靠传输服务,我们可将其想象成,使用TCP协议的收发双方基于TCP连接的可靠信道进行数据传输。
不会出现误码、丢弃、乱码以及重复等传输差错。TCP适用于要求可靠传输的应用,例如文件传输。
4.4 协议对比
UDP构成
一个UDP用户数据报由首部和数据载荷两部分构成,其首部格式如图所示,仅有4个字段,每个字段长度为2个字节。由于UDP不提供可靠的传输服务,它仅仅在网际层的基础上,添加了用于区分应用进程的端口。因此它的首部非常简单,仅有8个字节。
TCP构成
一个TCP报文段由首部和数据载荷两个部分构成,其首部格式如图所示,这比UDP用户数据报的首部复制的多,其最小长度为20个字节。最大的长度为60个字节,这是因为TCP要实现可靠传输,流量控制,拥塞控制等服务。其首部自然会比较复杂,首部中的字段比较多,首部长度也比较长。
4.5 小结
5- TCP控制
5.1 TCP的流量控制
5.1.1 基本概念
5.1.2 案例分析
步骤分析1
假设主机A和B是因特网上的两台主机,它们之间已经建立了TCP连接,A给B发送数据,B对A进行流量控制。这是主机A中待发送数据的字节序号。假设主机A发送的每个TCP数据报文段可携带100字节数据。因此图中每个小格子表示100个字节数据的序号,在主机A和B建立TCP连接时,B告诉A:"我的接收窗口为400"。主机A将自己的发送窗口也设置为400。这意味着主机A在未收到主机B发来的确认时,可将序号落入发送窗口中的全部数据发送出去。
步骤分析2
主机B对A的流量控制,主机A将发送窗口内序号1~100的数据封装成一个TCP报文段发送出去。发送窗口内还有300字节可以发送,这里的seq是TCP报文段首部中的序号字段,取值1表示TCP报文段数据载荷的第一个字节的序号是1。
这里的DATA表示这是TCP数据报文段,主机A将发送窗口内序号101200的数据封装成一个TCP报文段发送出去,发送窗口内还有200字节可以发送。主机A将发送窗口内还有200字节可以发送。主机A将发送窗口内序号201300的数据,封装成一个TCP报文段发送出去。但该报文段在传输过程中丢失了,主机A发送窗口内还有100个字节可以发送,主机B对主机A所发送的201号以前的数据进行累计确认。
并在该累计确认中将窗口字段的值调整为300,也就是对主机A进行流量控制。这里的大写ACK是TCP报文段首部中的标志位,取值1表示这是一个TCP确认报文段,小写ack是TCK报文段首部中的确认号字段。取值201表示序号201之前的数据已全部正确接收,现在希望收到序号201及其后续数据。rwnd是TCP报文段首部中的窗口字段,取值300表示自己的接收窗口大小为300。
步骤分析3
主机A收到该累计确认后,将发送窗口向前滑动,使已经发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了300。主机A相应地将自己的发送窗口调整为300。主机A发送窗口内的序号为201500,也就是主机A还可以发送这300字节,201300号字节是已发送的数据,如果重传计时器超时,它们会被重传。301400字节以及401500号字节还未被发送,可分别封装在一个TCP报文段中发送,主机A现在可将发送缓存中序号1~200的字节数据全部删除了。
因为已经收到了主机B对它们的累计确认,主机A将发送窗口内序号301400的数据封装成一个TCP报文段发送出去,发送窗口内还有100字节可以发送。主机A将发送窗口内序号401500的数据,封装成一个TCP报文段发送出去。至此,序号落在发送窗口内的数据已经全部发送出去了,不能再发送新数据了。
步骤分析4
现在,发送窗口内序号201~300这100个字节数据的重传计时器超时了,主机A将它们重新封装成一个TCP报文段发送出去,暂时不能发送其他数据。主机B收到该重传的TCP报文段后,对主机A所发送的501号以前的数据进行累计确认,并在该累计确认中将窗口字段的值调整为100,这是主机B对主机A进行的第二次流量控制。
步骤分析5
主机A收到该累计确认后,将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了100。因此,主机A相应地将自己的发送窗口调整为100。目前,主机A发送窗口内的序号为501600。也就是主机A还可以发送这100字节,主机A现在可将发送缓存中序号201500的字节数据全部删除了,因为已经收到了主机B对它们的累计确认。
步骤分析6
主机A将发送窗口内序号501600的数据,封装成一个TCP报文段发送出去。至此,序号落在发送窗口内的数据已经全部发送出去了,不能在发送新数据了。主机A所发送的601号以前的数据进行累计确认,并且在改累计确认中将窗口字段的值调整为0,这是主机B对主机A进行的第三次流量控制,主机A收到该累计确认后,并且将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了0。因此,主机A相应地将自己的接收窗口调整为0。目前,主机A不能再发送一般的TCP报文段了。主机A现在可将发送缓存中的序号501600的字节数据全部删除了,因为已经收到了主机B对它们的累计确认。
步骤分析7
假设主机B向主机A发送了零窗口的报文段后不久,主机B的接收缓存又有了一些存储空间。于是,主机B向主机A发送了接收窗口等于300的报文段。然而,这个报文段在传输过程中丢失了,主机A一直等待主机B发送的非零窗口的通知,而主机B也一直等待主机A发送的数据,如果不采取措施,这种互相等待而形成的死锁局面将一直持续下去。
步骤分析8
TCP为每一个连接设有一个持续计时器。只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器超时,就发送一个零窗口探测报文,仅携带一字节的数据。而对方在确认这个探测报文段时,给出自己现在的接收窗口值。如果接收窗口仍然是0,那么收到这个报文段的一方就重新启动持续计时器。如果接收窗口不是0,那么死锁的局面就可以被打破了。
主机A收到零窗口通知时,就启动一个持续计时器。当持续计时器超时时,主机A立刻发送一个仅携带一字节数据的零窗口探测报文段。假设主机B此时的接收窗口又为0了。主机B就在确认这个零窗口探测报文段时给出自己现在的接收窗口值为0,主机A再次收到零窗口通知,就再次启动一个持续计时器。当持续计时器超时,主机A立刻发送一个零窗口探测报文段。假设主机B此时的接收缓存又有了一些存储空间,于是将自己的接收窗口调整为了300,主机B就在确认这个零窗口探测报文段时,给出自己现在的接收窗口值为300,这样就打破了死锁的局面。
步骤分析9
主机A所发送的零窗口探测报文段到达主机B时,如果主机B此时的接收窗口仍然为0,那么主机B根本就无法接受该报文段,又怎么会针对该报文段给主机A发回确认时?实际上TCP规定,即使接收窗口为0,也必须接受零窗口探测报文段、确认报文段、以及携带有紧急数据的报文段。
如果零窗口探测报文段丢失了,会出现怎样的问题呢? 还能否打破死锁的局面吗?
能打破死锁的局面,因为零窗口探测报文段也有重传计时器,当重传计时器超时后,零窗口探测报文段会被重传。
5.1.3 小结
5.2 TCP的拥塞控制
5.2.1 基本概念
5.2.2 拥塞控制的算法
条件设定
5.2.3 慢开始和拥塞避免
慢开始
步骤流程1
传输轮次是指: 发送方给接收方发送数据报文段后,接收方给发送方发回相应的确认报文段。一个传输轮次所经历的时间,其实就是往返时间。往返时间并非是恒定的数值。使用传输轮次是为了强调,把拥塞窗口所允许发送的报文段都连续发送出去,并且收到了对已发送的最后一个报文段的确认。
纵坐标是拥塞窗口,它会随网络拥塞程度以及所使用的拥塞控制算法动态变化,在TCP双方建立逻辑连接关系时,拥塞窗口的值被设置为1,如下图标出传输轮次0时的拥塞窗口值为1,另外,还需要设置慢开始门限的初始值。本例采用16发送方每收到一个新报文段的确认时,就把拥塞窗口值加1,然后开始下一轮的传输,当拥塞窗口值增长到慢开始门限值时,就改为执行拥塞避免算法。
步骤流程2
由于发送方当前的拥塞窗口值是1,而发送窗口值等于拥塞窗口值,发送方当前只能发送一个TCP数据报文段,换句话说,拥塞窗口值是几,就能发送几个数据报文段。发送方发送0号数据报文段,接收方收到后,给发送方发回对0号报文段的确认报文段,发送方收到该确认报文段后,将拥塞窗口值加1增大到2,这意味着发送方。现在可以发送12号共两个数据报文段。接收方收到后,给发送方发回对12号报文段的确认报文段,发送方收到后,将拥塞窗口值增加2增大到4。
步骤流程3
发送方现在可以发送36号共四个数据报文段。接收方收到后,给发送方发回对36号报文段的确认报文段。发送方收到后,将拥塞窗口值加4增大到8,发送方现在可以发送714号共8个数据报文段。接收方收到后,给发送方发回对714号报文段的确认报文段,发送方收到后,将拥塞窗口值加8增大到16。
发送方当前的拥塞窗口值,已经增大到了慢开始门限值。之后,然后要改用拥塞避免算法。
拥塞避免
步骤流程1
每个传输轮次结束后,拥塞窗口值只能线性加1,而不像慢开始算法那样,每个传输轮次结束后,拥塞窗口值按指数规律增大,发送方现在可以发送1530号共16个数据报文段,接收方收到后。给发送方发回对1530号报文段的确认报文段。发送方收到后,将拥塞窗口值加1增大到17。
步骤流程2
在图中标出该值,发送方现在可以发送3147号共17个数据报文段,接收方收到后,给发送方发回对3147号报文段的确认报文段。发送方收到后,将拥塞窗口值加1增大到18。
步骤流程3
在图中标出该值,随着传输轮次的增加,拥塞窗口值每轮次都线性加1。当前拥塞窗口值增加到类4,发送方现在可以发送171~194号共24个数据报文段。假设这24个数据报文段在传输过程中丢失了几个。这必然会造成发送方对这些丢失报文段的超时重传。发送方以此判断网络很可能出现了拥塞。
步骤流程4
发送方以此判断网络很可能出现了拥塞,需要进行以下工作。(1) 将慢开始门限值更新为发生拥塞时拥塞窗口值得一半,网络发送拥塞时的拥塞窗口值是24,因此更新慢开始门限值为该值的一半,即12。(2) 将拥塞窗口值减小为1,并且重新开始执行慢开始算法。
步骤流程5
当慢开始算法执行到拥塞窗口值,增大到新的慢开始门限值时,就停止使用慢开始算法。转而执行拥塞避免算法。
步骤流程6
TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按指数规律增大。当拥塞窗口值增大到慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。当发生超时重传时,就判断网络很可能出现拥塞。采取相应的措施,一方面将慢开始门限值,更新为发生拥塞时拥塞窗口值得一半。另一方面将拥塞窗口值减少为1,并且从新开始执行慢开始的算法,拥塞窗口值又从1开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
5.2.4 快重传和快恢复
快重传(fast retrasmit)
快恢复(fast recovery)
改进后的整体算法的示意图
步骤流程
TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按指数规律增大,当增大到慢开始门限初始值时,停止使用慢开始算法。转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。当发生超时重传时,就判断网络可能出现了拥塞,采取相应的措施。一方面将慢开始门限值更新为发生拥塞时拥塞窗口值的一半。另一方面将拥塞窗口值减少为1,并重新开始执行慢开始算法。
拥塞窗口值又从1开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。当发送方收到3个重复确认时,就进行快重传和快恢复。也就是更新慢开始门限值为当前拥塞窗口值的一半,并将拥塞窗口值也取为新的慢开始门限值,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
5.3 TCP超时重传时间的选择
5.3.1 基本概念
步骤流程1
主机A给主机B发送TCP数据报文段0,并且记录下当前的时间。主机B收到后,给主机A发送相应的确认报文段。主机A收到确认报文段后,记录下当前的时间。那么主机A记录下的这两个时间,它们的差值就是报文段的往返时间RTT。
如果超时重传时间RTO的值设置得比RTT0的值小很多,这会引起报文段不必要的重传,使网络负荷增大。
步骤流程2
如果超时重传时间RTO的值设置得远大于RTT0的值,这会使重传时间推迟的太长,使网络的空闲时间增大,降低传输效率。
步骤流程3
注意:TCP下层是复杂的互联网环境,主机A所发送的报文段,可能只经过一个高速率的局域网,也有可能经过多个低速率的网络,每个IP数据报的转发路由还可能不同。
5.3.2 超时重传时间
RFC6298建议使用下式计算超时重传时间RTO
5.3.3 往返时间RTT的测量比较复杂
存在问题
当发送方出现超时重传后,收到确认报文段时,是无法判断出该确认,到底是对原报文段的确认。还是对重传报文段的确认,也就是无法准确测量出RTT,进而无法正确计算超时重传时间RTO。
解决方案
5.3.4 TCP超时重传的计算
步骤分析1
这是测量到的第一个RTT样本RTT1,根据RTTs1的计算公式可知RTTs1的值。根据RTTs1的计算公式可知RTTs1的值。根据RTTD1的计算公式可知RTTD1的值,再根据RTO的计算公式可计算出RTO1的值。这是测量到的第二个RTT样本RTT2。根据RTTs的计算公式和 α的值,可写出计算RTTs2的表达式。将之前计算出的RTTs1的值和本次测量到的RTT2的值带入该式,可计算出RTTs2的值。
步骤分析2
根据RTTD的计算公式和 β的值,可以写出计算RTTD2的表达式。将之前计算出的RTTD1、RTTs1、以及本次测量到的RTT2的值代入该公式,可计算出RTTD2的值,再根据RTO的计算公式可计算出RTO2的值。
步骤分析3
假设这是测量到的第五个RTT样本,但是根据RTO4的值可知,在收到确认之前就会产生超时重传。则不采用上述公式计算RTO,而是将新RTO的值取为旧RTO值的两倍。因此RTO5的值取为两倍的RTO4的值。
5.3.5 小结
5.4 TCP可靠传输的实现
5.4.1 案例说明
步骤流程1
假定数据传输只在一个方向进行,发送方给接收方发送TCP数据报文段,接收方给发送方发送相应的TCP确认报文段,这样的好处是使讨论仅限于两个窗口,也就是发送方的发送窗口和接收方的接收窗口。TCP的滑动窗口是以字节为单位的。
步骤流程2
假设发送方收到了一个来自接收方的确认报文段,在报文段首部中的窗口字段的值为20,也就是接收方表明自己的接收窗口的尺寸为20字节。确认号字段的值为31,这表明接收方希望收到下一个数据的序号是31,而序号30为止的数据已经全部正确接收了。
步骤流程3
发送方根据这两个字段的值构造出自己的发送窗口,假定网络不存在拥塞问题,也就是发送方在构造自己的发送窗口时,仅仅考虑接收方的接收窗口,而不是考虑拥塞窗口。发送方在没有收到接收方确认的情况下,可以把发送窗口内的数据依次全部发送出去。凡是已经发送过的数据,在未收到确认之前,都必须暂时保留,以便在超时重传时使用。发送窗口后沿的后面部分,是已发送并收到确认定位数据字节的序号,这些数据字节显然不需要再保存在发送缓存中了,可以将它们删除。发送窗口前沿的前面是当前不允许发送的数据字节的序号,发送窗口的后沿不可能向后移动,因为不能撤销掉已收到的确认。
如何描述发送窗口的状态?
假定发送方将发送窗口内序号31-41的数据,封装在几个不同的报文段中发送出去。此时发送窗口的位置并没有改变。发送窗口内序号3141的数据已经发送但是未收到确认,而序号4250的数据是允许发送但是还未发送的。可以使用三个指针P1,P2,P3分别指向相应的字节序号。
步骤流程4
继续看接收方的接收窗口,它的尺寸为20。在接收窗口外面到30号为止的数据,是已经发送过相应确认并已交付给应用进程的数据。因此无需再保留这些数据,可将它们从接收缓存中删除了。接收窗口内31~50号数据是允许接收的数据,接收窗口外51号及其后续数据,目前不允许接收。假设发送方之前发送的,封装有32和33号数据的报文段到达了接收方。
由于数据序号落在接收窗口内,所以接收方接受他们。将它们存入接收缓存,但是,它们是未按序到达的数据,因为31号数据还没有到达,这有可能丢了,也有可能是滞留在网络中的某处。请注意:接收方只能对按序收到的数据中的最高序号给出确认。因此,接收方发出的确认报文段中的确认序号仍然是31,也就是希望收到31号数据,窗口字段的值仍然是20,表明接收方没有改变自己接收窗口的大小。
发送方收到该确认报文段后,发现这是一个针对31号数据的重复确认,就知道接收方收到了未按序到达的数据。由于这是针对31号数据的第一个重复确认,因此这并不会引起发送方针对该数据的快重传。另外,接收方通知的窗口尺寸仍是20。现在假设封装有31号数据的报文段到达了接收方,接收方接受该报文段,将其封装的31号数据存入接收缓存。
将其封装的31号数据存入接收缓存,接收方现在可将接收到的31~33号数据交付给应用进程。然后将接收窗口向前移动3个序号,并给发送方发送确认报文段。该确认报文段中窗口字段的值仍为20,表明接收方没有改变自己接收窗口的大小。确认号字段的值为34,这表明接收方已经收到了序号33为止的全部数据。
步骤流程5
现在,假设又有几个数据报文段到达了接收方,它们封装有37、38以及40号数据。这些数据的序号虽然落在接收窗口内,但它们都是未按序到达的数据,只能先暂存在接收缓存中。
假设接收方先前发送的确认报文段到达了发送方,发送方接收后,将发送窗口向前滑动3个序号。
发送窗口的尺寸保存不变,这样就有新序号5153落入发送窗口内,而且序号3133移出了发送窗口,现在可将31~33号数据从发送缓存中删除了,因为已经收到了接收方针对它们的确认。
发送方继续将发送窗口内序号42~53的数据,封装在几个不同的报文段中发送出去。现在,发送窗口内的序号已经用完了,发送方在未收到接收方来确认的情况下,不能再发送新的数据。序号落在发送窗口内的已发送数据,如果迟迟收不到接收方的确认,则会产生超时重传。
5.4.2 解决方案
6- TCP的运输连接管理
6.1 基本概念
6.2 TCP的连接建立
前置步骤
- TCP 建立连接的过程叫做握手。
- 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。
- 采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
TCP的连接建立要解决以下三个问题
6.2.1三报文握手建立连接
流程步骤1
TCP 连接的建立采用客户服务器方式,主动发起连接建立的应用进程叫做TCP客户 (client)。被动等待连接建立的应用进程叫做TCP服务器 (server)。
“握手”需要在TCP客户端和服务器之间交换三个TCP报文段,最初两端的TCP进程都处于关闭状态。
流程步骤2
一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息。例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针,当前的发送和接收序号等之后,就准备接受TCP客户端进程的连接请求。此时,TCP服务器进程就进入监听状态,等待TCP客户端进程的连接请求。
TCP服务器进程是被动等待来自TCP客户端进程的连接请求,因此成为被动打开连接
流程步骤3
TCP客户进程也是首先创建传输控制块,由于TCP连接建立是由TCP客户端主动发起的,因此称为主动打开连接。然后,在打算建立TCP连接时,向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态。TCP连接请求报文段首部中,同步位SYN被设置为1,表明这是一个TCP连接请求报文段。序号字段seq被设置了一个初始值x,作为TCP客户端进程所选择的初始序号,请注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号。
流程步骤4
TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态TCP连接请求确认报文段首部中,同步位SYN和确认为ACK都设置为1,表明这是一个TCP连接请求确认报文段,序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号。确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号(seq)的确认。请注意:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号。
TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已连接状态。普通的TCP确认报文段首部中确认位ACK被设置为1,表明这是一个普通的TCP确认报文段,序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,所以TCP客户进程发送的第二个报文段的序号为x+1。确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认。请注意:TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号。
流程步骤5
TCP服务器进程收到该确认报文段后也进入连接已建立状态,现在,TCP双方都进入了连接已建立状态,它们可以基于已建立好的TCP连接,进行可靠的数据传输。
6.2.2 两报文握手
为什么TCP客户进程最后还要发送一个普通的TCP确认报文段?能否使用“两报文握手”建立连接?
流程步骤
TCP客户进程发出一个TCP连接请求报文段、但该报文段在某些网络结点长时间滞留了,这必然会造成该报文段的超时重传,假设重传的报文段被TCP服务器进程正常接收。TCP服务器进程给TCP客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态。
请注意: 由于我们改为"两报文握手"
因此TCP服务器进程发送完TCP连接请求确认报文段后,进入的是连接已建立状态,而不像"三报文握手"那样进入同步已连接状态,并等待TCP客户进程发来针对TCP连接请求确认报文段的普通确认报文段。TCP客户进程收到TCP连接请求确认报文段后,进入TCP连接已建立状态。但不会给TCP服务器进程发送针对该报文段的普通确认报文段。现在,TCP双方都处于连接已建立状态。它们可以相互传输数据。之后,可以通过“四报文挥手”来释放连接,TCP双方都进入了关闭状态。
一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段、到达了TCP服务器进程。TCP服务器进程会误认为这是TCP客户进程,又发起一个新的TCP连接请求。于是给TCP客户进程发送TCP连接请求确认报文段,并进入连接已建立状态。该报文段到达TCP客户进程,由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但是TCP服务器进程已经进入连接已建立状态,它认为新的TCP连接已经建立好了,并且一直等待TCP客户进程发来数据,这将白白浪费TCP服务器进程所在主机的很多资源。
得出结论
采用"三报文握手"而不是"两报文握手"来建立TCP连接,是为了防止已失效的连接请求报文段突然又传送到了TCP服务器,因而导致错误。
6.2.3 小结
6.3 TCP的连接释放
6.3.1 前置步骤
- TCP 连接释放过程比较复杂。
- 数据传输结束后,通信的双方都可释放连接。TCP 连接释放过程是四报文握手。
6.3.2 四报文挥手来释放连接
- TCP 连接的建立采用客户服务器方式。
- 主动发起连接建立的应用进程叫做TCP客户 (client)。
- 被动等待连接建立的应用进程叫做TCP服务器 (server)。
- 任何一方都可以在数据传送结束后发出连接释放的通知
6.3.3 执行流程
流程步骤1
现在TCP客户进程和TCP服务器进程都处于连接已建立状态,TCP客户进程的应用进程通知其主动关闭TCP连接。TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态,TCP连接释放报文段首部中。终止位FIN和确认为ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1,确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1。请注意:TCP规定终止位FIN等于1的报文段即使不携带数据,也要消耗掉一个序号。
流程步骤2
TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态,普通的TCP确认报文段首部中。确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配,确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认。
流程步骤3
TCP服务器进程应该通知高层应用进程,TCP客户进程要断开与自己的TCP连接。此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了。这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了。但如果TCP服务器进程还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭。
流程步骤4
TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接。
流程步骤5
TCP服务器进程发送TCP连接释放报文段并进入最后确认状态,该报文段首部中。终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认,序号seq字段的值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送。确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。
流程步骤6
TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态。该报文段首部中确认为ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认。TCP服务器进程收到该报文段后就进入关闭状态,而TCP客户进程还要进过2MSL后才能进入关闭状态。
TCP客户进程在发送完最后一个确认报文后,为什么不直接进入关闭状态?而是要进入时间等待状态?
TCP服务器进程发送TCP连接释放报文段后进入最后确认状态。TCP客户进程收到该报文段后,发送普通的TCP确认报文段,并进入关闭状态而不是时间等待状态。然而,该TCP确认报文段丢失了。这必然会造成TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,并仍处于最后的确认状态。重传的TCP连接释放报文段到达TCP客户进程。由于TCP客户进程属于关闭状态,因此不理睬该报文段,这必然会造成TCP服务器进程反复重传TCP连接释放报文段,并一直处于最后确认状态而无法进入关闭状态。因此,时间等待状态以及处于该状态2MSL时长,可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态。另外,TCP客户进程在发送完最后一个TCP确认报文段后,再经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段。
6.4 TCP保活计时器的作用
TCP双方已经建立了连接,后来,TCP客户进程所在的主机突然出现了故障。
TCP服务器进程以后就不能再收到TCP客户进程发来的数据,因此,应当有措施使TCP服务器进程不要再白白等待下去。
7- TCP报文段的首部格式
7.1 基本概念
7.2 源端口和目的端口
源端口和目的端口的作用
假设主机中的浏览器进程,要访问Web服务器中的Web服务器进程。当在浏览器地址栏中输入了Web服务器的域名后,浏览器进程会构建一个封装有HTTP请求报文的TCP报文段,该报文段首部中的源端口字段会填写一个短暂端口号,例如49152,用来标识发送该报文段的浏览器进程。目的端口字段会填写熟知端口号80,因为使用HTTP协议的Web服务器进程默认监听该端口。
Web服务器收到该TCP报文段后,从中解封出HTTP请求报文,并根据TCP报文段首部中目的端口字段的值,将HTTP请求报文上交给Web服务器进程。Web服务器进程根据HTTP请求报文的内容进行相应处理,并构建一个HTTP响应报文。HTTP响应报文需要封装成TCP报文段进行发送。该报文段首部中的源端口字段会填写熟知端口号80,用来标识发送该TCP报文段的Web服务器进程。而目的端口字段会填写49152,这是主机中需要接收该TCP报文段的浏览器进程所对应的端口号。
主机收到该TCP报文段后,从中解封出HTTP响应报文,并根据TCP报文段首部中目的端口字段的值49152,将HTTP响应报文上交给浏览器进程。浏览器进程对HTTP响应报文的内容进行解析并且显示。
7.3 序号、确认号和确认标志位
流程步骤
TCP客户进程发送一个TCP报文段,该报文段首部中序号字段的取值为201,这表示该TCP报文段数据载荷的第一个字节的序号为201。假设数据载荷的长度为100字节,首部中确认号字段的取值为800,这表示TCP客户进程收到了TCP服务器进程发来的,序号到799为止的全部数据,现在期望收到序号从800开始的数据。为了使确认号字段有效,首部中的确认标志位ACK的值必须设置为1。
TCP服务器进程收到该报文段后,也给TCP客户进程发送TCP报文段。该报文段首部中序号字段的取值为800,这表示该TCP报文段数据载荷的第一个字节的序号为800,这正好与TCP客户进程的确认相匹配。
假设数据载荷的长度为200字节。首部中确认号字段的取值为301,这表示TCP服务器进程收到了TCP客户进程发来的,序号到300为止的全部数据,现在期望收到序号从301开始的数据。为了使确认号字段有效,首部中的确认标志位ACK的值必须设置为1。
7.4 数据偏移、保留、窗口和校验和
分析
假设这个TCP报文段首部中的数据偏移字段的取值为二进制的0101,那么首部长度就为20字节。因为二进制0101的十进制值是5,而该字段以4字节为单位,因此5乘以4字节等于20字节。
分析
假设这个TCP报文段首部中的数据偏移字段的取值为二进制的1111,那么首部的长度就为60字节,因为二进制1111的十进制是15,而该字段以4字节为单位,因此15乘以4字节等于60字节。
注意事项
发送窗口的大小还取决于拥塞窗口的大小,也就是应该从接收窗口和拥塞窗口中的取小者,TCP报文段首部中的检验和字段。
7.5 同步标志位、终止标志位、复位标志位、推送标志位、紧急标志位和紧急指针
同步标志位
TCP通过"三报文握手"建立连接的过程。TCP客户进程发送的TCP连接请求报文段,首部中的同步标志位SYN被置于1,表明这是一个TCP连接请求报文段。TCP服务器进程发送的TCP连接请求确认报文段,首部中的同步标志位SYN被置1,确认位ACK也被置1,表明这是一个TCP连接请求确认报文段。
终止标志位
不管是TCP客户进程还是TCP服务器进程,它们所发送的TCP连接释放报文段,首部中的终止标志位FIN都被置1,表明这是TCP连接释放报文段。
复位标志位
推送标志位
紧急标志位和紧急指针