TCP协议复习

TCP包结构

  • 序号(Sequence Number):指定了当前数据分片中分配给首字节数据的序列号,用来解决包乱序问题。
  • 确认号(Acknowledgement Number):表示期望接受下一个数据分片的序列号,用来解决不丢包的问题。
  • 标志位(Flags):从低位到高位值依次为FIN,SYN,RST,PSH,ACK,URG,用来标识包的类型。
  • 窗口(Window):表示滑动窗口的大小,用于解决流量控制问题。

TCP协议状态机

初始化序号(ISN)为什么不是固定值

  • 防止伪造TCP包:若初始化序号是静态的,那么容易被伪造,如果是动态变化的,则增加了安全性,起码伪造的序号要在对方的滑动窗口范围之内。
  • 防止混淆新的连接和旧的连接的tcp包:比如发送rst之后,或者允许端口的reuse,那么网络上就很可能存在旧的连接的tcp包,动态的初始化需要能一定程度防止这种情况。

TIME_WAIT为什么是2MSL

假设A发送了ACK报文后过了一段时间t之后B才收到该ACK,则有 0 < t <= MSL。因为A并不知道它发送出去的ACK要多久对方才能收到,所以A至少要维持MSL时长的TIME_WAIT状态才能保证它的ACK从网络中消失。同时处于LAST_ACK状态的B因为收到了ACK,所以它直接就进入了CLOSED状态,而不会向网络发送任何报文。所以晃眼一看,A只需要等待1个MSL就够了,但仔细想一下其实1个MSL是不行的,因为在B收到ACK前的一刹那,B可能因为没收到ACK而重传了一个FIN报文,这个FIN报文要从网络中消失最多还需要一个MSL时长,所以A还需要多等一个MSL。

backlog

在linux 2.2以前:
在底层维护一个由backlog指定大小的队列。服务端收到SYN后,返回一个SYN/ACK,并把连接放入队列中,此时这个连接的状态是SYN_RECEIVED。当客户端返回ACK后,此连接的状态变为ESTABLISHED。队列中只有ESTABLISHED状态的连接能够交由应用处理。第一种实现方式可以简单概括为:一个队列,两种状态。
linux 2.2以后:
在底层维护一个SYN_RECEIVED队列和一个ESTABLISHED队列,当SYN_RECEIVED队列中的连接返回ACK后,将被移动到ESTABLISHED队列中。backlog指的是ESTABLISHED队列的大小。SYN_RECEIVED队列的大小由/proc/sys/net/ipv4/tcp_max_syn_backlog系统参数指定,ESTABLISHED队列由backlog和/proc/sys/net/core/somaxconn中较小的指定。

原文地址:https://www.cnblogs.com/HachikoT/p/13995223.html