TCP
三次握手
SYN同步位,建立连接时,用于同步序号
ACK确认位,当且仅当ACK = 1时,确认号字段有效
-
SYN = 1, ACK = 0
==> 是连接请求报文 -
SYN = 1, ACK = 1
==> 表示同意连接
seq初始序列号,ack确认号(期望收到的下一个保温第一个数据字节的序号),均占4字节
FIN终止位,用于释放连接
建立流程
客户端 -> SYN-SENT状态 - SYN = 1, seq = x
--> 服务端 -> LISTEN状态
客户端-> ESTABLISHED <-- SYN = 1, ACK = 1, seq = y, ack = x + 1
服务端 -> SYN-RCVD状态
客户端 - ACK = 1, seq = x + 1, ack = y + 1
--> 服务端 -> ESTABLISHED状态
四次挥手
注意:
TIME-WAIT 2MSL
(Maximum Segment Life 最大报文存活时间)
- 为什么是这个值?
- 客户端发送ACK后,如果服务端没有收到 ==> 服务端超时重传一个FIN,客户端再发送一个ACK并重置time-wait为2MSL
- 如果服务端收到了,不会发送任何消息,等待2MSL后从客户端发送过去的ACK报文和从服务端发送过来的FIN报文都不再存活
- ==> 可以放心释放资源及端口号
为什么建立连接是三次握手,关闭连接确是四次挥手呢?
建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。
而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
————————————————
原文链接:https://blog.csdn.net/qzcsu/article/details/72861891