运输层提供了端与端系统之间的逻辑通信(主机内部),而运输层提供了主机之间的逻辑通信,也就意味着运输层不存在中间路由器中。运输层在应用层与网络层之间至少提供最基础的多路复用和多路分解的服务,通过socket将应用层多个进程的数据收集交付网络层;或将网络层数据交付到不同的端口号的socket,提供给应用层的进程。
UDP
不可靠,面向无连接,首部字段少(8个字段)。UDP中只有源端口和目的端口,从网络层到达数据,只要目的端口一样,不管源端口是否一致,都会将数据提供给同个socket。
校验和:检验报文段在传输到目的端口前,32比特是否发生了改变。
发生方:会将源端口,目的端口,长度三个16位的比特分别相加,如果发生溢出,则末位加1。然后将结果取反,作为检验和的内容。
TCP
面向连接,可靠的运输层传输控制协议。
一、TCP报文段格式
虽然TCP面向字节流,但TCP传输的数据单元却是报文段。TCP报文段分为TCP首部和数据部分,TCP报文段首部的前20个字节是固定的,后面有4*n字节根据需要动态添加的选项,最大长度为40字节。
- 源端口和目的端口 各占两个字节,TCP的分用功能也是通过端口实现的。
- 序号 占4个字节,范围是[0,232],TCP是面向字节流的,每个字节都是按顺序编号。例如一个报文段,序号字段是201,携带数据长度是100,那么第一个数据的序号就是201,最后一个就是300。当达到最大范围,又从0开始。
- 确认号 占4个字节,是期望收到对方下一个报文段的第一个字节的序号。若确认号=N,则表示序号N前所有的数据已经正确收到了。
- 数据偏移 占4位,表示报文段的数据部分的起始位置,距离整个报文段的起始位置的距离。间接的指出首部的长度。
- 保留 占6位,保留使用,目前为0.
- URG(紧急) 当URG=1,表明紧急指针字段有效,该报文段有紧急数据,应尽快发送。
- ACK(确认) 仅当ACK=1时,确认号才有效,连接建立后,所有的报文段ACK都为1。
- PSH(推送) 接收方接收到PSH=1的报文段,会尽快交付接收应用经常,不再等待整个缓存填满再交付。实际较少使用。
- RST(复位) RST=1时,表明TCP连接中出现严重差错,必须是否连接,再重连。
- SYN(同步) 在建立连接时用来同步序号。当SYN=1,ACK=0,则表明是一个连接请求报文段。SYN=1,ACK=1则表示对方同意连接。TCP建立连接用到。
- FIN(终止) 用来释放一个连接窗口。当FIN=1时,表明此报文段的发送方不再发送数据,请求释放单向连接。TCP断开连接用到。
- 窗口 占2个字节,表示发送方自己的接收窗口,窗口值用来告诉对方允许发送的数据量。
- 校验和 占2字节,检验和字段查验范围包括首部和数据部分。
- 紧急指针 占2字节,URG=1时,紧急指针指出本报文段中的紧急数据的字节数(紧急字节数结束后为普通字节)。
- 选项 长度可变,最长可达40字节。例如最大报文段长度MSS。MSS指的是数据部分的长度而不是整个TCP报文段长度,MSS默认为536字节长。窗口扩大,时间戳选项等。
二、丢包情况
由于网络层的丢包并不会显式告知运输层,TCP推断丢包主要通过超时和三次冗余ACK报文段两种方式来推断网络出现丢包。
超时/重传机制解决报文段丢失问题 。超时时长需要大于发送方发送报文段到接收该报文段的确认的往返时间RTT。而RTT在不同时刻会有较大的波动,需要在某个时刻测量报文段的往返时间,称之为样本往返时间SampleRTT
。
SampleRTT
并不能反映一段时间内RTT的波动情况,因此需要求个均值:
$$
EstimatedRTT=(1-a)EstimatedRTT+aSampleRTT
$$
a的参考值为0.125。
$$
EstimatedRTT=0.875EstimatedRTT+0.125SampleRTT
$$
测量SampleRTT
的偏差情况也是有帮助的:
$$
DevRTT=(1-a)DevRTT+a|SmapleRTT-EstimatedRTT|
$$
a的推荐之为0.25
在上述相关时间的确定下,TCP超时时隔的设置:
$$
EstimatedRTT+4*DevRTT
$$
三、连接管理
1、连接建立:三次握手
三次握手图例如下,与文字解释配合使用效果更佳。
第一次:客户端发送连接请求报文给服务端,其中SYN=1,seq=x。发送完毕后进入SYN_END状态。
第二次:服务端接收到报文后,发回确认报文,其中ACK=1,ack=x+1,因为需要客户端确认,所以报文中也有SYN=1,seq=y的信息。发送完后进入SYN_RCVD状态。
第三次:客户端接收到报文后,发送确认报文,其中ACK=1,ack=y+1。发送完客户端进入ESTABLISHED
状态,服务端接收到报文后,进入ESTABLISHED
状态。到此,连接建立完成。
三次握手原因
避免资源被浪费掉。如果在第二步握手时,由于网络延迟导致确认包不能及时到达客户端,那么客户端会认为第一次握手失败,再次发送连接请求,服务端收到后再次发送确认包。在这种情况下,服务端已经创建了两次连接,等待两个客户端发送数据,而实际却只有一个客户端发送数据。
2、连接断开:四次挥手
四次挥手指客户端和服务端各发送一次请求终止连接的报文,同时双方响应彼此的请求。
四次挥手图例如下,请配置文字解释使用哦。
第一次挥手:客户端发送FIN=1,seq=x的包给服务端,表示自己没有数据要进行传输,单面连接传输要关闭。发送完后,客户端进入FIN_WAIT_1
状态。
第二次挥手:服务端收到请求包后,发回ACK=1,ack=x+1的确认包,表示确认断开连接。服务端进入CLOSE_WAIT
状态。客户端收到该包后,进入FIN_WAIT_2
状态。此时客户端到服务端的数据连接已断开。
第三次挥手:服务端发送FIN=1,seq=y的包给客户端,表示自己没有数据要给客户端了。发送完后进入LAST_ACK
状态,等待客户端的确认包。
第四次挥手:客户端收到请求包后,发送ACK=1,ack=y+1的确认包给服务端,并进入TIME_WAIT
状态,有可能要重传确认包。服务端收到确认包后,进入CLOSED
状态,服务端到客户端的连接已断开。客户端等到一段时间后也会进入CLOSED
状态。
四次挥手原因
由于TCP的连接是全双工,双方都可以主动传输数据,一方的断开需要告知对方,让对方可以相关操作,负责任的表现。
四、流量控制
原因:解决由于发送方发送数据速率与接收方接收数据数据不一致问题。
接收方接收窗口大小等于接收缓存大小减去已接收未被Socket读取的字节大小。
$$
rwnd=receiverBuff-unReadByte
$$
而发送方的发送窗口大小受限于拥塞窗口和接收窗口大小,即取两者最小值:
$$
swnd=min(rwnd,cwnd)
$$
流量控制主要采用了滑动窗口协议进行控制:
对于发送方接收缓存数据存在三种状态:
发送已确认 、发送未确认、未发送
而发送方接收缓存中数据存在两种状态:
已接收和确认但未被上层读取、接收未确认
五、拥塞机制
网络拥塞会导致路由器缓存溢出,而造成丢包,导致数据不可靠传输。而拥塞机制也正是解决该问题,告知TCP发送方如何调整发送速率,以将适量的数据交付到网络中,避免不要丢包,或者在丢包后,发送方应该如何调整速率。
网络拥塞带来的代价:
- 当分组到达速率接近链路容量时,分组会经历巨大的时延;
- 发送方必须执行重传已补偿因为缓存溢出而丢弃(丢失)的分组;
- 发送方遇到大时延所进行的不必要重传会引起路由器利用其链路带宽来转发不必要的分组;
- 当一个分组沿一条路被丢弃时,每个上游路由器用于转发改分组到丢弃该分组而使用的传输容量被浪费掉;
由于运输层无法显式从网络层获取到网络拥塞相关反馈,所有TCP只能借用超时和三个冗余ACK两种丢包情况来推断网络出现拥塞,从而进行端到端的拥塞控制。
TCP拥塞控制算法
分为三步骤:慢启动,拥塞避免,快速恢复
1、慢启动
拥塞窗口cwnd以一个MSS开始,每收到一个ACK报文段,则增1个MSS,即数据成指数增长。
以下三种情况会结束慢启动状态:
超时丢包:将cwnd置为1个MSS,慢启动阈值
ssthresh=cwnd/2
,重新开始慢启动;三次冗余ACK:此时判断网络出现拥塞而丢包,执行快速重传,进入快速恢复状态;
到达阈值:结束慢启动,进入拥塞避免;
2、拥塞避免
到达拥塞避免阶段,拥塞窗口在每个RTT内以1个MSS增长,成线性增长。
- 超时丢包:将cwnd置为1个MSS,慢启动阈值
ssthresh=cwnd/2
,重新开始慢启动; - 三次冗余ACK:此时判断网络出现拥塞而丢包,将拥塞窗口减少一半,进入快速恢复状态;
- 超时丢包:将cwnd置为1个MSS,慢启动阈值
3、快速恢复
此时
ssthresh=cwnd/2
,在Reno版本,如果接收到对丢包的报文段的冗余ACK报文段,拥塞窗口则增加一个MSS。拥塞窗口
cwnd=cwnd/2+3MSS(3次冗余ACK确认增加)
,然后线性增加。(拥塞避免)在Tahoe版本,拥塞窗口
cwnd=1MSS
,指数增长,达到ssthresh
进入线性增长。(慢启动操作,目前已弃用)- 丢包:将cwnd置为1个MSS,慢启动阈值
ssthresh=cwnd/2
,重新开始慢启动;
- 丢包:将cwnd置为1个MSS,慢启动阈值
六、总结
1、TCP判断可能出现丢包两种情况:
定时器超时
接收到三次冗余ACK(即对一个报文段接收到4次ACK报文段)
2、流量控制和拥塞控制都是为了让TCP能进行可靠数据传输,流量控制是为了解决接收方接收速率与发送方速率不一致问题,通过接收窗口大小告知发生方还能接收多大字节流。而拥塞控制是为了解决网络拥塞导致丢包问题,通过拥塞窗口扼制发送方发送过多分组到网络中。发送方的发送窗口大小受限于接收窗口和拥塞窗口的最小值。
七、相关连接
参考数据:《计算机网络 自顶向下》