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

三次握手建立连接


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

  • 第一次握手: 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状态意义
clientserverSYN确认报文SYN=1,seq=xSYN_SEND客户端请求发起连接, 等待服务器确认请求
serverclientSYN+ACK确认+同步报文SYN=1,ACK=1,seq=y,ack=x+1SYN_RECV服务器确认客户端的请求
clientserverACK确认报文ACK=1,ack=y+1,seq=x+1ESTABLISHEDESTABLISHED客户端确认, 连接完成

四次挥手关闭连接


在这里插入图片描述

  • 第一次挥手: 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状态意义
clientserverFINFIN=1,seq=uFIN_WAIT_1客户端 发起中断连接请求
serverclientACKSYN=1,ACK=1,seq=v,ack=u+1FIN_WAIT_2CLOSE_WAITClient端就进入FIN_WAIT_2状态,继续等待Server端的FIN报文
serverclientFINFIN=1,ACK=1,seq=w,ack=u+1LAST_ACK服务器数据发完了,准备好关闭连接了
clientserverACKFIN=1,ACK=1,seq=u+1,ack=w+1TIME_WAIT可以断开连接

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

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

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

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

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

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

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


client
在这里插入图片描述
server
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值