深入学习TCP协议

274 阅读7分钟

传输层协议TCP/UDP共有的作用:进程间通信(复用和分用)

复用和分用

复用指所有应用层的进程可以通过传输层通信,分用指传输层可以区分网络层数据报里应该对应的应用进程。通过套接字(SOCKET)来标识进程
套接字=主机IP地址+端口号

端口号是16位

  • 服务端固定端口:1~1023(FTP21/TELENT23/SMTP25/DNS53/TFTP69/HTTP80/SNMP161)
  • 服务端动态端口:1024~49151
  • 客户端动态端口:49152~65535

TCP

特点

  • 面向连接:在数据传输之前要建立连接.数据传输之后要释放连接

TCP数据交换方式是虚电路(分组+面向连接),IP数据交换方式是数据报(分组+无连接)

  • 滑动窗口机制保证可靠传输
  • 面向字节流,如果应用层的数据过长,会切割成报文段
  • 点对点的,不能多播或广播
  • 全双工通信

作用:可靠传输+流量控制+拥塞控制

可靠传输(确认重传)

可靠=无比特差错(校验)+无帧差错(序号、确认、重传)

确认重传(arq),是后退n帧+选择重传综合版本
采用累计确认,发送ack为4表明收到了1、2、3(和数据链路层不一样)
接收方有缓存(接收窗口大于1),不会将没收到帧之后到达的帧直接丢弃,而是放到缓存区

流量控制(滑动窗口)

接收方在ack报文段中报告自己的接收窗口大小rwnd
发送窗口大小=min{接收窗口大小,拥塞窗口大小}

拥塞控制

流量控制是局部的,拥塞控制是全局性防止过多数据注入网络,发送方动态设计的窗口值。其大小随传输轮次改变。

慢开始+拥塞避免快重传+快恢复
有两个临界值warn-number(比如16)和max-number(比如24)
慢开始+拥塞避免:从0到warn-number之间用指数算法增大(1、2、4、8...);warn-number和max-number之间用加法增大
快重传+快恢复:直接从warn到max用加法增大
最开始的时候以及拥塞窗口到max-number会触发慢开始+拥塞避免
收到三个冗余ack会触发快重传+快恢复 慢开始+拥塞避免慢开始+拥塞避免 慢开始+拥塞避免快重传+快恢复

协议

序号seq:该报文段第一个字节在整个TCP连接字节流中的序号
确认号ack:下一个报文段第一个数据字节的序号
数据偏移:该报文段离起始位置的字节数/4
标志位ACK(确认位):ACK为1时,确认号ack才有效
标志位SYN(同步位):SYN=1是连接请求/连接接收报文
标志位FIN(终止位):FIN=1时释放连接请求

TCP连接建立-三次握手

客户端和服务端都是 未连接-半连接-完全连接

  1. 客户端发送建立连接请求 SYN=1,seq=x
  2. 服务端发送建立连接确认 SYN=1,seq=y,ACK=1,ack=x+1
    服务端为该TCP连接分配资源(缓存和变量)
  3. 客户端发送建立连接确认的确认,SYN=1,seq=x+1,ACK=1,ack=y+1
    客户端为该TCP连接分配资源(缓存和变量)
    seq是用上上个seq+1,ack是用上一个seq+1

只有两次握手可以吗,为什么要有第三次握手?
为了保证客户端存活,防止服务端在建立连接完成的情况下资源浪费.
每一次握手,都是发送方告知接收方"我准备好了",本应该两次握手就足够
如果没有第三次握手,可能有这样的场景:客户端发送的某一个建立连接请求延迟很久,已经失效(这时候客户端早已经关闭连接),在服务端第二次握手完成,就认为建立好了连接
这时服务端会一直等待客户端发送数据,造成资源浪费 (基于两次握手,成功建立连接的模型 | 基于两次握手,未成功建立连接模型<因为失效的SYN造成资源浪费>)

三次握手的能保证服务端资源不被浪费吗?
不能,三次握手只能保证不会出现建立连接完成的情况下的浪费资源,但可能出现半连接的情况下的浪费资源
服务端在第二次握手完成后会等待第三次握手,处于半连接状态,一直收不到第三次握手的会一直发送第二次握手的报文段,浪费资源
SYN洪泛攻击就是利用这种特性,用大量的半连接消耗服务器的CPU和内存,最后导致服务端死机 (SYN洪泛攻击模型-客户端攻击者不发生第二次握手的报文段)

TCP连接释放-四次挥手

当第二次握手完成,双工通信变成单工通信,称为半关闭状态
释放连接的主动方可以是客户端,也可以是服务端,这里以客户端为例。

  1. 客户端发送连接释放请求 FIN=1,seq=u
  2. 服务端回应连接释放确认 ACK=1,seq=v,ack=u+1
  3. 服务端发送连接释放请求 FIN=1,ACK=1,seq=w,ack=u+1
  4. 客户端回应连接释放确认 ACK=1,seq=u+1,ack=w+1

三次挥手可以吗,为什么要有四次?
为什么要有第四次挥手,原因类似于为什么要有第三次握手,都是服务端为了确认连接建立请求/连接释放请求是有效的,而不是很久之前的一个超时报文段
释放连接为什么会比建立连接多一次,是因为释放连接的第二+第三次挥手对应建立连接第二次握手。建立只用处理连接,而释放连接要处理连接+数据,释放连接的第二次挥手后,服务端还有数据要发送,所以要把确认(第二次挥手)和释放请求(第三次挥手)分开。

Time-Wait等待2MSL的作用是什么?
MSL是一个数据包在网络中最大的生存时间,比如在以太网内,最大的生存时间就是受到TTL的约束,最多经过15个路由器。2MSL不等同于RTT(RTT两个传播时延)。MSL是理论上最大的生存时间,而RTT是实际上的往返时间。
客户端在发送完第四次的确认报文段后会等待2MSL才正真关闭连接。目的是确保服务端收到了这个确认报文段。
如果服务端没有收到第四次握手的确认报文段,服务端会在MSL后再次发送第三次挥手的释放连接请求。
2MSL是第四次挥手的最大生存时间+重发的第三次挥手报文段的最大生存时间。**如果在2MSL内没有收到重发的第三次挥手报文段,客户端则认为服务端已经成功接受到第四次挥手。**正式关闭连接。

最后对比看一下UDP👇

UDP

特点

  • 无连接
  • 没有差错控制机制,不是可靠传输
  • 面向报文,不切割应用层的数据,应用层给什么样的报文,UDP发送什么样的完整报文
  • 无拥塞控制机制

作用:实现组播

协议

其中UDP长度=首部(8B)+数据部分