5.1 运输层协议概述

运输层协议向应用层提供通信服务,一般而言只有主机的协议栈才有运输层,而路由器的协议栈一般只到网络层。
真实的数据交互发生在进程之间们,所谓真正端到端的通信最终都是两端主机上的进程通信。
image.png
传输层主要使用两种协议:面向连接的TCP和面向无连接的UDP,对应用层屏蔽细节,应用层看起来只是两个应用进程间的通信。
image.png
常用的TCP和UDP协议:
image.png
为了实现不同操作系统、不同主机的应用层通信,运输层提供了协议端口号,它是一种抽象的软件端口,与主机和操作系统无关,作为应用层和运输层交互的一种地址(层间接口)。实际通信时,需要知道对方的IP(找到主机)和端口号(找到通信的进程)
image.png
登记类端口:1024 ~ 49151
客户端端口:49152~65535,客户端进程动态使用,用完后就释放。


5.2 UDP协议

三个重要特点:面向连接、尽最大努力交付、面向报文(对于应用层报文直接在前面加上UDP头后,透明传输,如果要做分片则会在IP层)
image.png
UDP报文首部各字段:
(1)源端口:发送端应用的使用的端口号
(2)目的端口:接收端的目的端口号
(3)长度:UDP数据部分的长度
(4)校验和:UDP首部和数据部分的校验和,使用时需要添加12个字节的伪首部(仅作校验和用),校验时进行双字对齐(如果没对齐,则补零),发送方按照二进制反码求这些双字的和然后填写,接收方继续按照二进制反码求双字的和,最后如果双方校验和结果一致,说明正确。
image.png
image.png
如果接收方UDP发现报文中的目的端口不正确,则会发送一个ICMP报文,表示端口不可达。

image.png


5.3 TCP协议

特点:
(1)面向连接:传输前需要建立TCP连接(三次握手),传输完成后需要进行TCP连接释放(四次挥手);
(2)连接点对点:每条TCP连接只能有两个端点,点对点;
(3)提供可靠交付的服务:无差错、无乱序、不丢失、不重复;
(4)全双工通信:双方可进行同时收发,设有收发缓存区
(5)面向字节流:把应用层下发的数据都看做无结构的字节流,从应用层下发的字节流会先进入TCP窗口中缓存,达到一定量才会发送,TCP发送和接收的数据块不一定对等,但应用层与TCP交互的字节流必须一样。
image.png
TCP的连接:TCP连接的端点叫套接字
(1)Sokcet = {IP地址:端口号}
(2)一条TCP连接={Socket1,Socket2}={IP1:Port1,IP2:Port2}
**

5.3.1 可靠传输的工作原理

停等式ARQ:发送端每发送一个分组,等到接收端回复一个确认后,才开始接着发下一分组;如因链路质量出现延迟达到的情况,重复分组会丢弃。
image.png
连续ARQ:接收端无需对每一个分组进行确认,而是收到多个分组(窗口)时,给出一次确认,提高了链路传输效率。
image.png

5.3.2 TCP协议报文字段

TCP虽然是面向字节流的,但传输单元却是报文段,一个TCP报文段分为首部和数据两部分。
image.png
image.png
image.png
image.png
image.png
image.png

5.3.3 TCP可靠传输的实现

A为发送端,目前的发送窗口长度为20,而B期望收到的下一个报文序号为31,A在发送TCP报文时会在报文首部的窗口字段声明自己的窗口大小(发送方的窗口不能超过接收端窗口,发送窗口一般根据接收窗口设置),发送窗口越大传输效率显然越高。
发送窗口的前沿:一般是不动(没有收到确认)和前移(收到确认),后移的情况TCP标准不建议这样做(传输过程中TCP发送窗口突然缩小)。
image.png
image.png
image.png
image.png
image.png
TCP缓存与应用层字节流的关系
image.png
image.png
image.png

5.3.4 TCP流量控制

所谓流控:发送方别发太快,让接收方能够处理的过来。
大写的ACK表示应答为,置位1说明是应答报文,小写的ack才是对期待的下一次报文序号
死锁情况:如果在B的缓冲区满后,过了一段时间缓冲区可用了,但在发给A的过程中报文丢失,则A会等B的缓冲区可用应答,B会等A的数据,造成死锁;因此,如果A在收到B的缓冲区满后的报文后,会开启一个持续计时器,如果持续计数器时间到了后,B仍然没有给出缓冲区可用的报文,那A就会告诉B缓冲区已满,希望B重发其缓冲区大小。
image.png
针对传输效率,Nagle算法常在TCP实现中使用
image.png
image.png

5.3.5 TCP拥塞控制

在网络中,网络负载>网络资源容量,就会出现拥塞,不同于流控(只是收发双方),这是一个全局问题。
image.png
TCP拥塞控制的方法:慢启动、拥塞避免、快重传、快恢复。
慢启动:
(1)发送方维持一个拥塞窗口,让自己的发送窗口始终等于拥塞窗口;
(2)思路:主机开始发送数据时,并不清楚网络中的状况,所以先少量数据注入,测试网络状况,也就是慢启动,发送窗口的数值渐渐增大。
image.png
image.png
拥塞避免:让拥塞窗口缓慢增大,每经过一个RTT往返时间,就让窗口加1(这里窗口是以报文段为单位,实际中应当以字节为单位,假设窗口为10个mss长度,而每个mss长度为1460字节,则窗口为14600字节,而发送方可以连续发送14600字节,接收方每收到1个mss长度的字节流就会回复一个ACK,而窗口每次增加0.1个mss,当接收方回复10个ack时,刚好窗口增加一个报文段的长度),而非慢启动中的成倍增长。
image.png
快重传:接收方在接收数据时,不是在下次发送数据时捎带ack确认,而是立即发送确认消息,例如接收方已经收到了M1和M2,本该收到M3时,却收到了M4,应当立即发送重复M2的确认,表示希望收到M3。只要发送方连续收到三个重复确认,则会立即快速重传。
image.png
快恢复:发送方仅是丢了个别报文,还未引起网络拥塞,因此不启动慢启动,而采用快恢复,拥塞窗口减半,慢开始门限值也与拥塞窗口一样。
image.png

5.3.6 TCP运输连接管理

TCP的传输有三个过程:连接建立、数据传输、连接释放。

5.3.6.1 TCP的连接建立(三次握手)

1.首先客户端A和服务器B都处于连接关闭CLOSED状态,由A主动发起发起请求,B处于监听请求状态,从而A主动将状态从CLOSED变为SYN-SENT(连接请求状态)而B从CLOSED变为LISTEN状态
2.A发送SYN=1的连接建立请求报文(SYN是TCP首部中的同步字段,1表示这是连接建立报文),报文序号seq=x;B接收到seq=x的报文后,从LISTEN状态转为SYN-RCVD状态,发送SYN=1,ACK=1(大写ACK=1表示这是一个响应报文)seq=y,ack=x+1(小写ack表示期待的下一报文序号),表示同意建立连接,
3.A收到连接建立响应报文后,从SYN-SENT状态转为ESTABLISHED连接建立状态,并发送ACK=1,seq=x+1,ack=y+1的响应,表示已经收到了B的连接响应报文;B收到改报文后,也从SYN-SENT状态进入ESTABLISHED状态,至此三次握手完成;
注意:

  • 如果是两次握手,那B的响应报文可能存在丢失的情况,这样A就不知道B到底有没有接收自己的连接请求;另外,如果A在发送一个连接报文后,B迟迟没有收到,过了很长一段时间后B收到了,但此时A已经不想建立连接了,B给A的响应报文,A不理睬,B却以为已经建立好了连接,一直等A的数据,浪费大量资源。
  • 如果是四次握手,则会造成资源的浪费,因为再多一次的握手并没有必要,效果是一样的;如果双方一直等待对方的确认,还会陷入死锁。

image.png

5.3.6.2 TCP的连接释放(四次挥手)

1.目前A和B都处于ESTABLISED的连接已经建立状态,A向B发送FIN=1(表示连接释放请求),seq=u的报文,进入FIN-WAIT-1状态,FIN不携带数据,但也消耗一个序号。
2.B收到该报文后,进入CLOSE-WAIT状态(TCP半关闭状态),给予响应ACK=1,seq=v,ack=u+1的报文,A收到响应后进入FIN-WAIT-2状态,同时从如果有未发送的数据,则继续发送。
3.然后B向A发送FIN=1(表示连接释放请求),seq=w,ack=u+1的报文,进入LAST-ACK状态
4.A收到B的连接释放请求报文后,给予ACK=1,seq=u+1,ack=w+1的的响应报文,并进入TIME-WAIT状态,之后;B收到A的响应报文后,进入CLOSED状态,A经过2MSL(2倍的最长报文段寿命)后,也进入CLOSED状态.
TIME-WAIT设置2倍的最长报文段寿命的原因:

  • 防止B没有收到最后一个ACK,因为在2MSL内,B如果没有收到该报文会立即重传上一次的FIN=1,ACK=1报文,从而A继续重传对B的FIN报文的响应报文。
  • 经过2MSL,本次连接中所有的报文都会失效,从而A重新建立连接时,不会出现序号相同的旧报文。

image.png

5.3.6.3 TCP的有限状态机

image.png