5.1 运输层协议概述
5.1.1 进程之间的通信
运输层是面向通信的最高层,同时也是用户功能的最低层。
真正进行通信的实体是在
主机中的进程。
【注】运输层最近又增加了第三种协议,流控制传输协议SCTP(stream control transmission protocol),具有TCP和UDP协议的共同优点。
网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信。
网络层中,IP数据报首部中的校验和字段,只检验首部是否出现差错而不检查数据部分。
运输层需要对收到的报文进行
差错检测。
TCP相当于提供一条全双工的可靠信道。
UDP仍然是一条不可靠信道。
5.1.2 运输层的两个主要协议
用户数据报协议UDP
传输控制协议TCP
TCP不提供广播和多播服务。
服务端使用的端口号
- 熟知端口号 或 系统端口号 :0~1023
- 登记端口号:1024~49151
客户端使用的端口号:49152~65536
5.2 UDP
UDP的主要特点:
- 无连接的,即发送数据之前不需要建立连接
- 尽量最大交付,不保证可靠交付
- 面向报文,UDP对应用层交下来的报文,既不合并,也不拆分,照样发送,因此,应用程序必须选择合适大小的报文。
- 没有拥塞控制,因此网络出现拥塞时也不会使主机的发送速率降低。
- 弊端:网络拥塞时有些报文可能会丢失,因此UDP不可靠。
- 优点:有些使用场景允许报文丢失,如:直播、语音通话,但对实时性要求很高,此时UDP还是很有用武之地的。
- 支持一对一、一对多、多对一、多对多的交互通信。
- UDP首部开销小。只有8个字节,比TCP的20个字节短得多。
为了改进UDP的不可靠传输,应用进程可以在不影响应用的实时性的前提下,增加一些高可靠的措施,如采用前向纠错或重传已丢失的报文。
它主要用于不要求分组顺序到达的传输中,
分组传输顺序的检查与排序由应用层完成。
5.2.2 UDP的首部格式
校验和:检测UDP用户数据报在传输中是否有错,有错就丢弃。
伪首部仅仅是为了计算校验和,既不向上递交也不向下传送。
虽然在UDP之间的通信要用到端口号,但是由于UDP的通信是无连接的,因此不需要使用套接字。
IP数据报的校验和只检验IP数据报的首部,但UDP的校验和是把
首部和数据部分一起都检验。
5.3 TCP
TCP的主要特点:
- 面向连接的运输层协议
- 每一条TCP连接只能是两个端点,点对点。
- 提供可靠交付的服务。无差错,不丢失,不重复,有序
- 全双工通信。两端都有发送缓存和接收缓存。
- 面向字节流。流stream指的是流入到进程或从进程流出的字节序列。
TCP和UDP在发送报文时所采用的方式完全不同。
TCP不关心应用进程一次把多长的报文发送到TCP缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少字节;UDP发送的报文长度是应用进程给出的。
5.3.2 TCP的连接
TCP连接的端口叫做套接字socket或插口
端口号拼接到IP地址即构成了套接字。
每一条TCP连接唯一地被通信两端的两个端点所确定。
TCP连接就是由协议软件所提供的一种抽象。
5.4 可靠传输的工作原理
5.4.1 停止等待协议
确认重传机制
自动重传请求ARQ协议:意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。
5.4.2 连续ARQ协议
接收方一般采用
累积确认方式:接收方不必对收到的分组逐个发送确认,而是在收到几个分组后对按序到达的最后一个分组发送确认。表示这个分区为止的所有分组都已正确收到了。
5.5 TCP报文段的首部格式
TCP虽然是面向 字节流 的,但TCP传送的数据单元却是报文段。
在一个TCP连接中传送的字节流中
每一个字节都按顺序编号。
首部中的
序号:本报文段所发送的数据的第一个字节的序号。
确认号:期望收到对方下一个报文段的第一个数据字节的序号。
数据偏移:实际上指出了TCP报文段的首部长度,单位是4个字节。所以首部最长为4*15=60.
确认ACK:仅当ACK=1时
确认号 字段才有效。在连接建立后所有传送的报文段都必须把ACK置1.
同步SYN:置为1表示这是一个
连接请求或
连接接受报文。SYN=1,ACK=0时,表明这是一个连接请求报文。
终止FIN:用来释放一个连接,当FIN=1时,表明此报文段的发送方的数据以发送完毕,并要求释放运输连接。
窗口:指的是发送本报文的一方的
接收窗口的大小。
字节为单位。窗口值作为接收方让发送方设置其发送窗口的依据。
校验和:检验的范围包括首部和数据这两部分。和UDP一样,需要在前面加上12字节的伪首部,TCP的协议号为6。
紧急指针:在URG=1时才有意义,指出了紧急数据的末尾在报文段中的位置。注意:即使窗口为0也可以发送紧急数据。
最大报文段长度MSS,是每一个TCP报文段中
数据字段的最大长度。
MSS应尽可能大些,只要在IP层传输时不需要在分片就行。
时间扩大选项
时间戳选项
选择确认选项SACK
5.6 TCP可靠传输的实现
5.6.1 以字节为单位的滑动窗口
TCP的滑动窗口是以字节为单位的。(
具体细节看书)
5.6.2 超时重传时间的选择
重传时间的选择是TCP最复杂的问题之一。
TCP采用了一种自适应算法。
加权平均往返时间 又称 平滑的往返时间,S表示Smoothed
RFC6298推荐的a为0.125.
超时重传时间 RTO retransmission time-out
略大于
加权平均往返时间
如何判断此确认报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?
这对上面 加权平均往返时间 的计算影响很大。
5.6.3 选择确认SACK
5.7 TCP的流量控制
5.7.1 利用滑动窗口实现流量控制
流量控制:让发送方的发送速率不要太快,要让接收方来得及接收。
利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
死锁:
为了解决上述问题,TCP为每一个连接设有一个
持续计时器(persistence timer),只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器设置的时间到期,就发送一个零窗口探测报文段。
TCP规定,即使设置为零窗口,也必须接收以下几种报文段:零窗口探测报文段、确认报文段和携带紧急数据的报文段。
5.7.2 TCP的传输效率
发送方在不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
5.8 TCP的拥塞控制
5.8.1 拥塞控制的一般原理
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这就叫
拥塞。
拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。
拥塞控制所要做的都有一个
前提,就是网络能够承受现有的网络负荷。
拥塞控制是一个全局性的过程。
流量控制往往是指点对点通信量的控制,是个端到端的问题。接收端控制发送端。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
5.8.2 TCP的拥塞控制方法
慢开始
拥塞避免
快重传
快恢复
1. 慢开始和拥塞避免
基于窗口的拥塞控制
发送方维持一个
拥塞窗口cwnd
拥塞窗口的大小决定于网络的拥塞程度。并且动态的变化。
发送方让自己的发送窗口等于拥塞窗口。
判断网络拥塞的依据就是出现了
超时。
TCP是用
字节作为窗口大小的单位。
SMSS是发送方的最大报文段的数值。
RTT:传输轮次
慢开始的“慢”并不是指cwnd的增长速度慢,而是指在TCP开始发送报文段时的初始值较小。这比一开始就把cwnd设置很大,让许多报文注入到网络中要慢得多。
为了防止拥塞窗口cwnd增长多大引起网络拥塞,还需设置一个
慢开始门限ssthresh
拥塞避免算法的思路是让拥塞窗口cwnd缓慢地增大。
“拥塞避免”算法并非完全能够避免拥塞,而是把拥塞窗口控制为按线性增长,使网络比较不容易出现拥塞。
采用
快重传算法可以让发送方尽早知道发生了个别报文段的丢失。
快恢复算法
AIMD算法:AI additive increase 加法增大,MD multiplicative decrease 乘法减小 两者结合
5.8.3 主动队列管理 AQM
为了避免发生网络中的
全局同步现象,提出了
主动队列管理AQM.
所谓主动就是不要等到路由器的队列长度已经达到最大值才不得不丢弃,应当在达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。
AQM可以有不同的实现方式,有一种 随机早期检测RED。
但多年实践证明RED的使用效果并不太理想,已不推荐使用,目前已经有几种算法处于实验阶段,但还没有一种能够成为IETF标准。
5.9 TCP的运输连接管理
运输连接的三个阶段:
连接建立
数据传输
连接释放
5.9.1 TCP的连接建立 三次握手
TCP规定:SYN报文段不能携带数据,但要消耗掉一个序号。
TCP规定:ACK报文段可以携带数据,但如果不携带数据则不消耗序号。
四次握手
为什么A最后还要发送一次确认呢?
5.9.2 TCP的连接释放 四次挥手
TCP规定:FIN报文段即使不携带数据,它也消耗掉一个序号。
MSL 最长报文段寿命 Maximum Segment Lifetime 建议设为2分钟。但这是工程的考虑,现在的网络,可以根据具体的情况使用更小的MSL值。
为什么A在TIME-WAIT状态必须等待2MSL的时间呢?
保活计时器 keepalive timer