三次握手
“3次握手”的作用就是
双方都能明确自己和对方的收、发能力是正常的
。
**第一次握手:**客户端A将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认;
**第二次握手:**服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态。
**第三次握手:**客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了。
- 第一次,客户端发送一个包,SYN=1, seq=x(随机),发到服务端,客户端进入SYN_SEND状态
- 第二次,服务端收到后发确认包,SYN=1, ACK=1, seq=y(随机), ACKnum=x+1,服务端进入SYN_RCVD状态
- 第三次,客户端收到后再次发确认包,ACK=1,ACKnum=y+1
- 客户端和服务端都进入
ESTABLISHED
状态
为什么需要三次握手
为了确认客户端和服务端都能有正常的数据发送和接收能力
避免服务端一直等待失效请求的数据传输,浪费资源
四次挥手
双方都可以关闭连接,现在假设客户端发起关闭请求
- 第一次,客户端发送一个FIN=1,seq=x的包,表示自己不会再发送数据了,但还可以接受数据,客户端进入FIN_WAIT_1状态
- 第二次,服务端发送确认包,ACK=1,ACKnum=x+1,表明接受客户端关闭连接的请求,服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT_2状态
- 第三次,服务端向客户端发送结束连接请求包,FIN=1,seq=y,服务端进入LAST_ACK状态
- 第四次,客户端发送确认包,ACK=1,ACKnum=y+1,状态变为TIME_WAIT状态(因为服务端有可能还会要求重传包)。服务端收到后关闭连接,进入CLOSED状态
- 客户端等待了一下,没有收到服务端请求重试的ACK,认为服务器已经关闭连接,于是自己也关闭,进入CLOSED状态
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
因为收到对方的FIN报文,仅仅表示对方不会再发送数据了,但是还能接收数据,己方是否现在关闭发送数据的通道还需要上层应用决定