2020-11-04

三次握手(使用 connect() 建立连接时)

 

  •  套接字A:“你好,套接字B,我这里有数据要传送给你,建立连接吧。”
  •  套接字B:“好的,我这边已准备就绪。”
  • 套接字A:“谢谢你受理我的请求。”

CLOSED:客户端调用 socket() 函数创建套接字后,因为没有建立连接,所以套接字处于CLOSED状态

LISTEN:服务器端调用 listen() 函数后,开始监听客户端请求,套接字进入LISTEN状态。

SYN-SEND:客户端调用 connect() 函数后,TCP协议会组建一个数据包,并设置 SYN 标志位,表示该数据包是用来建立同步连接的。同时生成一个随机数字 1000,填充“序号(Seq)”字段,表示该数据包的序号。完成这些工作,开始向服务器端发送数据包,客户端就进入了SYN-SEND状态。seq:1000(客户端发送了一个序号为1000的数据包)

SYN-RECV:服务器端收到数据包,检测到已经设置了 SYN 标志位,就知道这是客户端发来的建立连接的“请求包”。服务器端也会组建一个数据包,并设置 SYN 和 ACK 标志位,SYN 表示该数据包用来建立连接,ACK 用来确认收到了刚才客户端发送的数据包。

服务器生成一个随机数 2000,填充“序号(Seq)”字段。2000 和客户端数据包没有关系。seq:2000(服务器端发送一个序号为2000的数据包)

服务器将客户端数据包序号(1000)加1,得到1001,并用这个数字填充“确认号(Ack)”字段。Ack:1001(表示接收到客户端序号为1000的数据包)

服务器将数据包发出,进入SYN-RECV状态。

ESTABLISED(客户端):客户端收到数据包,检测到已经设置了 SYN 和 ACK 标志位,就知道这是服务器发来的“确认包”。客户端会检测“确认号(Ack)”字段,看它的值是否为 1000+1,如果是就说明连接建立成功。

客户端会继续组建数据包,并设置 ACK 标志位,表示客户端正确接收了服务器发来的“确认包”。同时,将刚才服务器发来的数据包序号(2000)加1,得到 2001,并用这个数字来填充“确认号(Ack)”字段。Ack:2001(表示收到服务器端发来的数据包)

客户端将数据包发出,进入ESTABLISED状态,表示连接已经成功建立。

ESTABLISED(服务器端):服务器端收到数据包,检测到已经设置了 ACK 标志位,就知道这是客户端发来的“确认包”。服务器会检测“确认号(Ack)”字段,看它的值是否为 2000+1,如果是就说明连接建立成功,服务器进入ESTABLISED状态。