欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TCP三次握手四次挥手详解

程序员文章站 2022-06-14 11:17:43
...

一、TCP报文首部(部分)

***seq***。根据***识别某个操作。占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;***seq就是这个报文段中的第一个字节的数据编号。

确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;***表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

确认ACK确认信号。占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

同步SYN请求建立连接。连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。

终止FIN希望断开连接。用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接

PS:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号。

专有名词:
SYN(synchronous 建立联机)
ACK(acknowledgement 确认)
PSH(push 传送)
FIN(finish 结束)
RST(reset 重置)
URG(urgent 紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码) ack
establish 建立,创建

二、三次握手理解

三次握手(Three-Way Handshake)即建立 TCP 连接,是指建立一个 TCP连接时,需要客户端和服务端总共发送 3 个包以确认连接的建立。

TCP三次握手四次挥手详解

  1. 第一次握手:建立连接。客户端发送连接请求报文段,将SYN位置为1,seq为x;然后,客户端进入SYN_SEND状态,等待服务器的确认;
  2. 第二次握手:服务器收到SYN报文段。服务器收到客户端的SYN报文段,需要对这个SYN报文段进行确认,设置ack为x+1(seq+1);同时,自己自己还要发送SYN请求信息,将SYN位置为1,seq为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,此时服务器进入SYN_RECV状态;
  3. 第三次握手:客户端收到服务器的SYN+ACK报文段。然后将ack设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。

完成了三次握手,客户端和服务器端就可以开始传送数据。

三、四次挥手理解

所谓四次挥手(Four-Way Wavehand)即终止 TCP 连接,就是数据传送完毕,要断开一个 TCP连接时,需要客户端和服务端总共发送 4 个包以确认连接的断开。

TCP三次握手四次挥手详解

  1. 第一次挥手:主机1(可以使客户端,也可以是服务器端)发出连接释放报文,并且停止发送数据,FIN=1,其***为seq=u,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了; TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

  2. 第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,ACK=1,ack=u+1(seq+1);主机1进入FIN_WAIT_2状态, 客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间

  3. 第三次挥手:主机2向主机1发送FIN报文段(连接释放报文),请求关闭连接,FIN=1,ack=u+1,此时,主机2就进入了LAST-ACK(最后确认)状态,等待客户端的确认

  4. 第四次挥手:主机1收到主机2发送的FIN报文段(连接释放报文),向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,ACK=1,ack=w+1,而自己的***是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间,2MSL时间后依然没有收到回复,则证明Server端已正常关闭,才进入CLOSED状态。可以看到,服务器结束TCP连接的时间要比客户端早一些。

四、Python中TCP网络应用程序开发

TCP三次握手四次挥手详解
在 socket 编程中,三次握手这一过程由客户端执行 connect 来触发

#客户端代码
#客户端首先发起请求连接服务器
import socket
host = '127.0.0.1'#设置ip
port = 8088 #端口
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))#连接服务端,三次握手触发

在socket编程中,四次挥手这一过程由客户端或服务端任一方执行 close 来触发

#服务器端代码
import socket
host = '127.0.0.1'#设置ip
port = 8088 #端口
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#连接服务端
s.bind((host,port))
s.listen(5)
print("服务端已开启,等待客户端连接...")
conn, addr = s.accept()#连接
print("客户端已连接...\n")

五、常见面试题

【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?

答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,“你发的FIN报文我收到了”。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

【问题3】为什么不能用两次握手进行连接?

答:为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
举一个例子:
"已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。"这就很明白了,防止了服务器端的一直等待而浪费资源。

【问题4】如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

参考:https://blog.csdn.net/qq_38950316/article/details/81087809

相关标签: tcp