TCP连接管理
- 连接建立
- 连接传输
- 连接终止
建立–三次握手
目的在于让通信双方了解一个连接正在建立,也利用数据报的选项来承载特殊的信息,交换初始序列号(Initial Sequence Number, ISN)
。
终止–四次挥手
要达到双方都安全关闭。
同时关闭与同时打开
同时打开需要交换四个报文段,比正常三次握手多一次。
- 两端在相同时刻发送
SYN
报文段,然后都进入SYN_SENT
状态 - 当接收到对方的
SYN_SENT
状态时,都变为SYN_RECV
状态 - 然后两端都重新发送一个新的
SYN
并确认之前收到的对方的SYN
- 当通信双方都收到了
SYN
和ACK
,状态均变为ESTABLISHED
同时关闭和正常关闭相同,交换四个报文段。
- 当要关闭连接时,通信双方状态都变为
FIN_WAIT_1
,于此同时,向对方发送一个FIN
- 当接收到对方来的
FIN
之后,两端通信状态从FIN_WAIT_1
变为CLOSING - 通信双方发送最终的
ACK
,两端状态变为TIME_WAIT
,然后等待2MSL
有趣的TCP选项
长度 | 名称 | 描述 |
---|---|---|
4 | MSS | 最大段大小,TCP 允许的从对方接收到的最大报文段,只记录数据的字节数,默认536字节 |
可变 | SACK | “选择确认”选项,其包含接收方已成功接收的数据块的序列号范围 |
3 | WSOPT | 滑动窗口缩放因子,能够将窗口的广告范围从16位增加到30位 |
10 | TSOPT | 时间戳选项,在每个报文段中添加2个4字节的时间戳,接收方在确认中反映该数值, 利用每个接收到的 ACK 估算RTT |
4 | UTO | 用户超时选项,表明TCP 发送者在对方未能成功接收数据之前愿意等待该数据ACK 确认的时间 |
可变 | TCP-AO | TCP 认证选项,增强连接的安全性,增强或替换TCP-MD5 机制,使用一种加密散列算法 |
ipv4
的经典最大段的大小数值为1460字节,加上TCP
头部和IP
头部共1550字节(以太网中最大传输单元MTU
与互联网路径最大传输单元的经典数值)ipv6
的经典最大段的大小数值为1440字节,因为ipv6
的头部比ipv4
头部长20个字节,20字节用于TCP
头部,40字节用于ipv6
头部SACK
选项只存在于SYN
报文段中SACK
提供了接收方已经成功接收的数据块的序列号范围,每个范围被称作一个SACK
块,由一对32位的序列号表示,一个SACK
选项包含n
个SACK
块,长度为 8 n + 2 8n+2 8n+2个字节。WSOPT
只能存在于SYN
报文段中,当连接建立之后比例因子是与方向绑定的。为保证窗口调整,通信双方都需要包含该选项TSOPT
,发送方将一个32位的数值填充到时间戳数值字段(称为TSV
)作为时间戳选项的第一部分,接收方将受到的时间戳数值不变地填充至第二部分的时间戳回显重试字段(称为TSER
)TSOPT
估算RTT
是为了设置重传超时,告知TCP
通信方何时应该重新发送可能已经丢失的数据段
TCP状态转换
TIME_WAIT状态
也成为2MSL
等待状态,该状态中,TCP
将会等待两倍于最大段生存期(Maximum Segment Lifttime, MSL)
的时间。他表示任何报文在被丢弃之前在网络中被允许存在的最长时间。
常见的MSL
可以为30秒,1分钟或2分钟。该值可以修改。
- 可靠地实现
TCP
全双工连接的终止——若最终发送的ACK
丢失,服务器需要重新发送FIN
,所以客户端需要维护状态信息 - 允许老的重复分组在网络中消失——关闭当前连接之后,过很短的时间以相同的
IP
地址和端口号建立另一个连接,后一个连接成为前一个连接的 化身,TCP
必须防止来自前一个连接的老的重复分组在新连接中再现,从而被误解成为新连接的分组。2MSL
足以让老的连接中某个方向的分组最多存活MSL
,另一个方向对最后分组的应答最多存活MSL
被丢弃。
FIN_WAIT_2 状态
某TCP
通信端已经发送一个FIN并得到另一端的确认。
若出现 半关闭 情况,正在关闭的TCP连接一端一直保持FIN_WAIT_2
,而另一端一直保持CLOSE_WAIT
状态。为避免这种情况出现,需要设置一个定时器,若当定时器超时时连接是空闲的,那么TCP
连接就会转移到CLOSED
状态。
TCP队列
TCP
存在两个队列,在SYN_RECV
存在一个snys_queue
半连接队列,在ESTABLISHED
存在accept_queue
全连接队列。
三次握手中
- 第一步
server
接收到SYN
数据段后,把相关信息放入半连接队列中,同时回复SYN+ACK
给client
(第二步) - 若
server
收到client
的ACK
后,若此时全连接队列没满,则从半连接队列中拿出相关信息放入全链接队列,否则客户端会进行多次重传,直至达到超时时间,client
会自己发送FIN
数据段,结束连接。
参考文献
- TCP/IP详解卷1