三次握手:
第一次握手:客户端向服务器端发起连接请求,客户端随机生成一个起始序列号ISN(比如是100),客户端向服务器端发送的报文段包括SYN标志位,(也就是SYN=1),和序列号seq=100
第二次握手:服务器收到客户端发来的报文,看到SYN=1,知道这是一个连接请求,于是将客户端的起始序列号100存起来,并随机生成服务器的起始序列号(比如300),然后给客户端回复报文,包括SYN=1和ACK=1,确认号ack=101(客户端序列号+1),序列号seq=300
第三次握手:客户端收到服务器的报文后,发现ACK=1,并且ack=101,知道服务器收到了序列号为100的报文了,同时发现SYN=1,知道服务器同意了连接请求,于是将服务器的序列号300保存起来,回复一段报文包括ACK=1,ack=301,seq=101,当服务器收到报文后发现ACK=1,ack=301,就知道客户端收到序列号=300的那段报文了,这样双方建立了连接
在sock编程中,客户端执行connect()时,触发三次握手
客户端:connect()
服务器:listen(),accept()
四次挥手:双方都处于ESTABLTISHED状态,假如由客户端发起关闭请求
第一次挥手:客户端发送连接释放报文,包含FIN=1标志位,指定一个序列号seq,此时客户端处于FIN_WAIT1状态 (FIN=1,seq=u)
第二次挥手:服务器收到FIN报文之后,会发送ACK报文,把客户端的序列号+1,作为ACK报文的序列号值,此时客户端处于CLOSE_WAIT状态,而不是马上给客户端发FIN报文,这个状态还要维持一段时间,因为服务器可能有数据没发完。(ACK=1,ack=u+1,seq=v)
第三次挥手:服务器向客户端发送连接释放报文,包含SYN和ACK标志位,确认号和第二次挥手一样,在指定一个序列号,服务器处于LAST_ACK状态(SYN=1,ACK=1,ack=u+1,seq=w)
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态(ACK=1,seq=u+1,ack=w+1)
收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。
|