5.1 传输层功能概述
传输层是只有主机才有的层次。为应用层提供通信服务,使用网络层的服务。
功能:
- 传输层提供进程和进程之间的逻辑通信(网络层提供主机与主机之间的逻辑通信)
- 复用和分用
- 传输层对收到的报文进行差错检测
- 传输层的两个协议(面向连接的传输控制协议TCP、无连接的用户数据报协议UDP)
5.2 复用与分用的概念
5.3 传输层的端口号
TCP/IP体系的应用层常用协议所使用的运输层熟知端口号
举例:在用户PC中使用网页浏览器来访问web服务器内容
- 在网页的地址栏中输入web服务的域名,用户PC中的DNS客户端进程会发送一个DNS查询请求报文,其内容为“域名××对应的IP地址是什么”,DNS的查询请求报文需要使用运输层的UDP协议,封装成UDP用户数据报,其首部中源端口号在49151~65535中任选一个未被占用的,用来表示DNS客户端进程,目的端口字段的值为DNS服务器端进程对应的端口号53,之后将用户数据报封装在IP数据报中通过以太网发送给DNS服务器。

- DNS服务器收到该数据报后,从中解封出UDP用户数据报,UDP首部中的目的端口号是53,这表明应将该UDP用户数据报的数据载荷部分(即DNS查询请求报文)交付给本服务器中的DNS服务器端进程。DNS服务器端进程解析DNS查询请求报文的内容,然后按照其要求查询对应的IP地址,之后,会给用户PC发送DNS响应报文,内容为“域名××对应的IP地址为××”。DNS响应报文使用运输层的UDP协议封装成用户数据报,其首部中的源端口字段值设置为53,表明这是DNS服务器端进程所发送的UDP用户数据报;目的端口设置为之前用户PC中发送DNS请求查询报文的DNS客户端进程使用的短暂端口号。之后,将用户数据报封装在IP数据报中通过以太网发送给用户PC。用户PC收到该数据报后从中解封出UDP用户数据报,将响应报文给用户PC的DNS客户端进行解析拿到IP地址。

- 用户PC向web服务器发送HTTP请求报文,内容为“首页内容是什么”,HTTP请求报文需要使用运输层的TCP协议封装成TCP报文段,源端口选取同上,目的端口为80,然后将TCP报文段封装在IP数据报中通过以太网发送给web服务器。

- web服务器收到该数据包后,从中解封出该报文段,将HTTP请求报文交付给HTTP服务器端进程,查找首页内容,之后会给PC发送HTTP响应报文,内容为HTTP客户端请求的首页内容,使用运输层的TCP协议封装成报文段,首部端口号与DNS类似,之后将TCP报文段封装在IP数据报中,通过以太网传给PC。

- 用户PC收到该数据报后,从中解封出TCP报文段,通过端口号80可知将TCP报文段的数据载荷部分交付给PC中的HTTP客户端进程,解析HTTP响应报文的内容,并在网页浏览器中显示。
5.4 TCP与UDP的对比
- 对比1:

- 对比2:

- 对比3:

基于TCP的两端是全双工通信,可以同时进行TCP报文段的发送和接收。
- 对比4

- 对比5:

- 总结: | 用户数据报协议UDP | 传输控制协议TCP | | —- | —- | | 无连接 | 面向连接 | | 支持一对一,一对多,多对一和多对多交互通信 | 每一条TCP连接只能有两个端点EP,只能是一对一通信 | | 对应用层交付的报文直接打包 | 面向字节流 | | 尽最大努力交付,即不可靠;不使用流量控制和拥塞控制 | 可靠传输,使用流量控制和拥塞 | | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
5.5 UDP
5.6 TCP
5.6.1 TCP的流量控制
1.概念
2.发送过程
初始化窗口大小为400,窗口是可以动态调整的,由接收端进行调整。接收端根据自己接收缓存的大小,动态调整发送方的发送窗口大小,即接收窗口rwnd(接收方设置确认报文段的窗口字段来将rwnd通知给发送方),发送方的发送窗口大小 = min[接收方窗口rwnd,自身拥塞窗口cwnd]

- 如果此时主机A所发送的零窗口探测报文段到达主机B时,如果此时B的接收窗口仍然为0,那么主机B根本就无法接受该报文段,如何向A发回确认?实际上TCP规定,即使接受窗口为0,也必须接受零窗口探测报文段、确认报文段、携带紧急数据的报文段。
如果零窗口探测报文段丢失了,将会出现什么问题,还能否打破死锁的局面么?可以。零窗口探测报文段也有重传计时器,当重传计时器超时后,零窗口探测报文段会被重传。
5.6.2 TCP的拥塞控制
1. 概念
2. 拥塞控制算法
假设如下条件:
数据是单方向传送,而另一个方向只传送确认;
- 接收方总是有足够大的缓存空间,因而发送方发送窗口的大小由网络的拥塞程度来决定;
- 以最大报文段MSS的个数为讨论问题的单位,而不是以字节为单位。
(1)慢开始
慢开始门限值ssthresh设定为16
第1轮传输,发送方的拥塞窗口cwnd=1,发送方发送0号数据报文段,接收方接收后,给发送方发送0号报文段的确认报文段,发送方收到后,将拥塞窗口值增大1,cwnd=1+1=2;
第2轮传输,发送方的拥塞窗口cwnd=2,发送方发送1-2号数据报文段,接收方接收后,给发送方发送1-2号报文段的确认报文段,发送方收到后,将拥塞窗口值增大2,cwnd=2+2=4;
第3轮传输,发送方的拥塞窗口cwnd=4,发送方发送3-6号数据报文段,接收方接收后,给发送方发送3-6号报文段的确认报文段,发送方收到后,将拥塞窗口值增大4,cwnd=4+4=8;
第4轮传输,发送方的拥塞窗口cwnd=8,发送方发送7-14号数据报文段,接收方接收后,给发送方发送7-14号报文段的确认报文段,发送方收到后,将拥塞窗口值增大8,cwnd=8+8=16;
当前拥塞窗口值=慢开始门限值,改用拥塞避免算法。
(2)拥塞避免
每个传输轮次结束后,拥塞窗口只能线性增加1。
第5轮传输,发送方的拥塞窗口cwnd=16,发送方发送15-30号数据报文段,接收方接收后,给发送方发送15-30号报文段的确认报文段,发送方收到后,将拥塞窗口值增大1,cwnd=16+1=17;
第6轮传输,发送方的拥塞窗口cwnd=17,发送方发送31-47号数据报文段,接收方接收后,给发送方发送31-47号报文段的确认报文段,发送方收到后,将拥塞窗口值增大1,cwnd=17+1=18;
…..随着轮次的增加,每次拥塞窗口值都线性加1
第12轮传播,发送方的拥塞窗口cwnd=24,发送方发送171-194号数据报文段,中途丢失了几个报文段,造成发送方对丢失报文段的超时重传,发送方以此判断网络很可能出现了拥塞,进行以下工作:
- 将ssthresh值更新为发生拥塞时的cwnd值的一半;
- 将cwnd值减少为1,并重新开始执行慢开始算法,达到ssthresh之后,再开始执行拥塞避免算法。
(3)快重传
注:快重传是还未达到超时重传的那个点。


(4)快恢复


5.6.3 TCP超时重传时间的选择
1. 超时重传时间过小
2. 超时重传过大
3. 正确超时重传时间选择
4. 超时重传时间选取复杂的原因
互联网环境复杂,网络的传输速率会有变化,且每个IP数据报的转发路由还可能不同。
5. 超时重传时间选取规则
6. 往返时间RTT的测量比较复杂
7.改进的计算规则
5.6.4 TCP可靠传输的实现


注意:TCP的接收窗口与数据链路层的SR协议不同,32、33都接受后返回的不是SR协议中的ack32、ack33,依然是当前按序收到的数据中的最高序号31,返回ack31(表明前30号已经收到了),接收端没有收到31号却收到了别的就把别的缓存起来,收到三次别的序号就发送三次ack31以进行快重传.
注意点:

5.6.5 TCP的运输管连接管理
1. TCP的连接建立
- 建立连接要解决的问题:

- TCP使用“三报文握手”建立连接过程
1.最初,两端的TCP进程处于关闭状态。TCP服务器进程首先创建传输控制块,存储TCP连接中的一些重要信息。
2.TCP服务器将进入监听状态,等待TCP客户进程的连接请求。服务器进程是被动等待客户进程的连接请求而不是主动发起,因此称为被动打开连接。
3.TCP客户进程首先创建传输控制块。在打算建立TCP连接时,向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态。TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段;序号字段seq被设置了一个初始值x,作为TCP客户进程所选择的初始序号(TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号)。由于TCP连接建立是由TCP客户主动发起的,因此称为主动打开连接。
4.TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态。该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段;序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号;确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号的确认(这个报文段也不能携带数据,同样消耗掉1个序号)。
5.TCP客户进程请求收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态,该报文段首部中的确认位ACK被设置为1,表明这是一个普通的TCP确认报文段;序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x并且不携带数据,因此第二个报文段的序号为x+1(TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号,在这种情况下,所发送的下一个数据报文段的序号仍是x+1);确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认。TCP服务器进程收到该确认报文段后也进入连接已建立状态。双方都进入连接已建立状态,可以进行可靠的数据传输了。

- 问题:为什么不能简化为“两报文握手”/最后一次是否多余?
如果是两报文握手,情况如下。第一个TCP连接请求如果滞留,发生超时重传,重新发送TCP连接请求。重传的TCP请求正常接收,TCP服务器进程给客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态,TCP客户进程收到TCP连接请求确认报文段后进入连接已建立状态。现在双方都进入了连接已建立状态,可以互相向双方发送数据,之后释放连接并进入关闭状态。当滞留的失效TCP连接请求报文段到达了TCP服务器进程,TCP服务器进程会误以为这是TCP客户进程又发起的新的TCP连接请求,于是给TCP客户进程发送TCP连接请求确认报文段并进入连接已建立状态。该报文段到达客户端进程,由于客户端进程没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但是TCP服务器进程认为已经建立好了,在等TCP客户进程发送数据,白白浪费TCP服务器进程所在主机的很多资源。防止已失效的连接请求报文段突然又传送到了TCP服务器,从而导致错误。
2.TCP的连接释放
- TCP通过“四报文挥手”来释放连接
TCP连接双方都可以主动释放连接。假设使用TCP客户进程的应用进程通知其主动关闭TCP连接,TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态。该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认;序号字段seq的值为u,它等于TCP客户进程之前已传送过的数据的最后一个字节的序号加1(TCP规定终止位FIN等于1的报文段即使不携带数据也要消耗掉1个序号);确认号字段ack设置为v,它等于TCP客户进程之前已收到的数据的最后一个字节的序号加1。
TCP服务器进程收到该连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态。该报文段首部中的确认为ACK的值设置为1,表明这是一个普通的TCP确认报文段,序号字段seq值为v,它等于TCP服务器进程之前已传送过的数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配;确认号报文段ack的值为u+1,这是对TCP连接释放报文段的确认。
TCP服务器进程这时应通知高层应用进程:TCP客户进程要断开与自己的连接。此时,从TCP客户进程到TCP服务器进程这个方向的连接就释放了,这时的TCP连接属于半关闭状态,也即TCP客户进程已经没有数据要发送了。但TCP服务器进程如果还有数据要发送,则TCP客户进程依然要接收,即从TCP服务器进程到TCP客户进程的连接没有关闭。这个状态可能会持续一段时间。TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。
若使用TCP服务器进程的应用金恒已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接。由于TCP连接释放室友TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放成为被动关闭连接。TCP服务器进程发送TCP连接释放报文段并进入最后确认状态。该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认;现在假定序号seq字段值为w,这是因为在半关闭状态下,TCP服务器进程可能又发送了一些数据;确认号ack的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。
TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段之后进入时间等待状态。该报文段首部中的确认为ACK的值被设置为1,表明这是一个普通的TCP确认报文段;序列号seq的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号;确认号ack的值设置为w+1,这是对所收到的TCP连接释放报文段的确认,TCP服务器进程收到该报文段后就进入关闭状态。而TCP客户进程还要经过2MSL后才能进入关闭状态(MSL:最长报文段寿命,RFC793建议为2分钟)。
- 问题:为什么TCP客户进程还需要2MSL时间才进入关闭状态?
如果TCP客户进程发送的确认报文段丢失了,会造成TCP服务进程对之前发送的TCP连接释放报文段超时重传,会一直处于最后确认状态。重传的TCP连接释放报文段到达TCP客户进程,由于TCP客户进程处于关闭状态,因此不理睬该报文段,这会造成TCP服务器进程反复重传TCP连接释放报文段,一直处于最后确认状态而无法进入关闭状态。
因此,时间等待状态以及处于该状态2MSL时长可以确保TCP服务器进程可以收到最后一个TCP确认报文段而进入关闭状态。另外,TCP客户进程在发送完最后一个TCP确认报文段后,在经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的TCP连接中,不会出现旧连接中的报文段。
- 保活计时器
5.6.6 TCP报文段的首部格式



