TCP三次握手

TCP报文段首部格式

TCP报文段首部格式

部分字段意义:

  • 序号

    占4字节,范围是[0,$$2^{32}-1$$]。增加到$$2^{32}-1$$之后,下个序号回到0。

    在一个TCP连接中传送的字节流中的每一个字节都按顺序编号。整个字节流的起始序号必须在建立连接时设置。

  • 确认号

    占4字节。是期望收到对方下一个报文段的第一个数据字节的序号。

    若确认号 == N,表明:到序列号N-1为止的所有数据都已经正确收到

  • 数据偏移

    它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。

  • 紧急URG(Urgent)

    当URG = 1时,表明紧急指针字段有效。它告诉系统此时报文段中有紧急数据。要与紧急指针(Urgent Pointer)字段配合使用。

  • 确认ACK(Acknowlegment)

    仅当ACK = 1时,确认号才有效。ACK = 0时,确认号无效。

    TCP规定:连接建立后所有传送的报文段都必须把ACK置1。

  • 复位RST(Reset)

    用于复位,RST = 1表示连接出现错误,应当立即关闭。当TCP接收到复位报文段后会通知应用程序连接被复位,随后关闭连接

  • 同步SYN(Synchronization)

    在连接建立时用来同步序号。

    当SYN = 1而ACK = 0时,表明这是一个连接请求报文段。

    若对方同意连接,则应在响应报文段中使SYN = 1和ACK = 1。

    所以只要SYN = 1,就表示这是一个连接请求或连接接受报文。

  • 终止FIN

    用于释放连接,报文段中FIN控制位为1表示已经将数据发送完毕,等待关闭连接

TCP的连接建立——三次握手(three-way handshake)

过程

假定最初两端的TCP进程都处于CLOSE状态。

  1. B的TCP服务器进程先创建传输控制块TCB,准备接受客户进程的连接请求。然后服务器进程就处于LISTEN(收听)状态,等待客户的连接请求。

  2. A的TCP客户进程也是首先创建传输控制模块TCB,然后向B发出连接请求报文段,首部中的同步位SYN = 1,同时选择一个初始序列seq = X

    TCP规定,SYN报文段(即SYN = 1的报文段)不能携带数据,但要消耗一个序号

    这时,TCP客户端进入SYN-SENT(同步已发送) 状态。

  3. B收到连接请求报文段之后,如果同意建立连接,则向A发送确认。确认报文段中SYN位ACK位都置为1,确认号是ack = X + 1,同时也为自己选择选择一个序列号seq = Y

    这个报文段也不能携带数据,同样消耗一个序号

    这时,TCP服务器进程进入SYN_RCVD(同步收到)状态。

  4. TCP客户端收到B的确认之后,向B再次确认。确认报文段中ACK位置为1,确认号ack = Y + 1,自己的序号seq = X + 1

    ACK报文段可以携带数据。但如果不携带数据则不消耗序号,这种情况下,下一个数据报文段的序号仍然是seq = X + 1。

    这时,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态

    B收到A的确认后,也进入ESTABLISHED状态

图示

sequenceDiagram
participant Client
participant Server
note over Client, Server: Client主动打开连接 
Server被动打开连接 Server ->> Server: TCP服务器进程创建传输控制块TCB note right of Server: 处于Listen
(收听)状态 Client ->> Client: TCP客户创建创建传输控制块TCB Client ->> Server: SYN=1, seq=X note left of Client: 进入SYN-SENT
(同步已发送)状态 note over Server: 收到连接请求报文,同意连接 Server ->> Client: SYN=1, ACK=1, seq=Y, ack=X+1 note right of Server: 进入SYN-RCVD
(同步收到)状态 Client ->> Server: ACK=1, seq=X+1, ack=Y+1 note left of Client: 进入ESTABLISHED
(已建立连接)状态 note right of Server: 进入ESTABLISHED
(已建立连接)状态 note over Client, Server: 连接已建立 Client -->> Server: 传输数据 Server -->> Client: 传输数据