Linux网络编程(三)—— TCP三次握手、四次挥手详解(图)

三次握手建立连接


TCP 发送数据之前要先建立连接(三次握手)
所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。
三次握手的目的是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换 TCP 窗口大小信息.在socket编程中,客户端执行connect()时。将触发三次握手。
两台主机,服务器(server)和客户机(client)
Linux网络编程(三)—— TCP三次握手、四次挥手详解(图)_第1张图片
过程:

  • 第一次握手: client将SYN位置1,随机产生一个值seq=x,并将该数据包发送给server,client进入SYN_SEND状态,等待server确认;
    client告诉server两件事
    ①我想要和你通信
    ②你可以用哪个序列号作为起始数据段来回应我

  • 第二次握手: server在收到包含SYN的报文之后,由于SYN位被值置1,知道client请求建立连接,server将SYN,ACK都置1,ack=x+1,随机产生一个值seq=y,并将该报文发送给client,server进入SYN_REVC状态;
    server告诉client两件事:
    ①我已经收到你的请求了,你可以传输数据了;
    ②你要用哪种序列号作为起始数据段来回应我

  • 第三次握手: client在收到server的SYN+ACK的报文之后,先检查ack是否为x+1,ACK是否为1,如果正确,就将ACK置为1,ack=y+1,并将报文发送给server,server会检查报文中的ACK是否为1,ack是否等于y+1,如果正确,client和server进入到ESTABLISHED状态,TCP连接建立。
    3次握手的特点
    ①没有应用层的数据
    ②SYN这个标志位只有在TCP建产连接时才会被置1
    ③握手完成后SYN标志位被置0

三次握手过程中client和server的状态

发送方 接收方 报文 数据包 client状态 server状态 意义
client server SYN确认报文 SYN=1,seq=x SYN_SEND 客户端请求发起连接, 等待服务器确认请求
server client SYN+ACK确认+同步报文 SYN=1,ACK=1,seq=y,ack=x+1 SYN_RECV 服务器确认客户端的请求
client server ACK确认报文 ACK=1,ack=y+1,seq=x+1 ESTABLISHED ESTABLISHED 客户端确认, 连接完成

四次挥手关闭连接


Linux网络编程(三)—— TCP三次握手、四次挥手详解(图)_第2张图片

  • 第一次挥手: client发送FIN报文(FIN=1,seq=u),表示client端发起中断连接请求,也就是发送FIN报文,发送完毕后client进入FIN_WAIT_1状态
  • 第一次挥手: server收到FIN报文后,如果还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以先回复ACK报文(ACK=1,seq=v,ack=u+1),发送完毕后server进入CLOSE_WAIT状态
  • 第一次挥手: server端确定数据已发送完成,则向client端发送FIN报文(FIN=1,ACK=1,seq=w,ack=u+1),表示它要关闭TCP连接,发送完毕后进入LAST_ACK状态
  • 第一次挥手: client收到FIN信号后,进入TIME_WAIT(倒计时)状态,接着发送一个ACK报文(FIN=1,ACK=1,seq=u+1,ack=w+1)给server。server收到该ACK后自行关闭,同时client超时后也关闭。连接关闭后,双方所有的资源都会被释放。

四次挥手过程中client和server的状态

发送方 接收方 报文 数据包 client状态 server状态 意义
client server FIN FIN=1,seq=u FIN_WAIT_1 客户端 发起中断连接请求
server client ACK SYN=1,ACK=1,seq=v,ack=u+1 FIN_WAIT_2 CLOSE_WAIT Client端就进入FIN_WAIT_2状态,继续等待Server端的FIN报文
server client FIN FIN=1,ACK=1,seq=w,ack=u+1 LAST_ACK 服务器数据发完了,准备好关闭连接了
client server ACK FIN=1,ACK=1,seq=u+1,ack=w+1 TIME_WAIT 可以断开连接

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。

其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,”你发的FIN报文我收到了”。

只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。

故需要四步握手。
总结:因为server端的FINACK是分开发送的。

三次握手和四次挥手的过程中,client和server的状态变化


client
Linux网络编程(三)—— TCP三次握手、四次挥手详解(图)_第3张图片
server
Linux网络编程(三)—— TCP三次握手、四次挥手详解(图)_第4张图片

状态 描述
CLOSED 关闭状态,没有连接活动或正在进行
LISTEN 监听状态,服务器正在等待连接进入
SYN RCVD 收到一个连接请求,尚未确认
SYN SENT 已经发出连接请求,等待确认
ESTABLISHED 连接建立,正常数据传输状态
FIN WAIT 1 (主动关闭)已经发送关闭请求,等待确认
FIN WAIT 2 (主动关闭)收到对方关闭确认,等待对方关闭请求
TIMED WAIT 完成双向关闭,等待所有分组死掉
CLOSING 双方同时尝试关闭,等待对方确认
CLOSE WAIT (被动关闭)收到对方关闭请求,已经确认
LAST ACK (被动关闭)等待最后一个关闭确认,并等待所有分组死掉

你可能感兴趣的:(网络通信,linux网络编程)