- 第一次握手:建立连接时,客户端发送
syn
包和一个随机序列号seq=x
到服务器,并进入SYN_SEND
状态,等待服务器进行确认。(syn
,同 步序列编号)。 - 第二次握手,服务器收到
syn
包,必须确认客户的SYN
,然后服务器发送一个ACK=1, SYN=1, seq=y
的随机数和ack=x+1
的确认数的包发送回去。 - 第三次握手是客户端收到服务器端的
SYN+ACK
包,然后向服务器端发送确认包ack=y+1, seq=x+1, ACK=1
,客户端和服务器端进入ESTABLISHED
状态,完成三次握手。具体图示如下(ACK
表示首部中的ACK
位置1,ack
表示首部中确认序号字段的值):
这里多说一点,既然提到了连接时的三次握手,就顺便把断开连接时的四次挥手也复习一下。
- 首先客户端主动发送
Fin=1,seq=u
,它等于前面已传 送过去的最后一个字节的序号加1.这时A
进入FIN-WAIT-1
状态,等待B
的确认。 B
收到连接后立即发出确认,确认号是ack=u+1
,而这个报文段 自己的序号是v
,等于B
前面已传送过的数据的最后一个字节的序号加1.然后B
即进入CLOSE-WAIT
状态。因而A
到B
的这个链接现在已经断开了,这时 的TCP
连接处于半关闭状态,即A
已经没有数据需要发送了。但B
若发送数据,A
还是要接受的。A
收到来自B
的确认之后就进入了FIN-WAIT-2
状态等 待B
发出连接释放报文段。- 若
B
已经没有要向A
发送数据,其应用进程就通知TCP
释放连接。这时B
发出的连接释放报文段必须使用FIN=1
.现在假定B
的序 号为w
,B
还必须重复上次已发送过的确认号ack=u+1
.这时B
就进入了LAST-ACK
状态,等待A
确认。 A
在收到B
的连接释放之后必须对此发出确 认。在确认号中把ACK
置1,确认号ack=w+1
,而自己的序号是seq=u+1
。接着A
进入TIME-WAIT
状态。为了保证B
可以收到确认释放报文段。如下图:
是不是所有执行主动关闭的socket
都会进入TIME_WAIT
状态呢?
有没有什么情况使主动关闭的socket
直接进入CLOSED
状态呢?
主动关闭的一方在发送最后一个 ack
后
就会进入 TIME_WAIT
状态 停留2MSL
(max segment lifetime
)时间
这个是TCP/IP
必不可少的,也就是“解决”不了的。也就是TCP/IP
设计者本来是这么设计的
主要有两个原因:
- 防止上一次连接中的包,迷路后重新出现,影响新连接
(经过
2MSL
,上一次连接中所有的重复包都会消失) - 可靠的关闭
TCP
连接在主动关闭方发送的最后一个
ack(fin)
,有可能丢失,这时被动方会重新发fin
, 如果这时主动方处于CLOSED
状态 ,就会响应rst
而不是ack
。所以主动方要处于
TIME_WAIT
状态,而不能是CLOSED
。
时间: 2024-10-11 11:23:44