三次握手/四次挥

TCP 三次握手/四次挥手
TCP 在传输之前会进行三次沟通,一般称为“三次握手”,传完数据断开的时候要进行四次沟通,一般称为“四次挥手”。

1.TCP3次握手

名词解释:

  • seq :Sequence Number 序列号,占4个字节,用来标记数据段的顺序,本地随机产生

  • ack:ACK:Acknowledgment Number 确认号,占4个字节,ack=seq+1

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

  • SYN:连接建立时用于同步序号

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

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

第一次握手

  • 建立连接。客户端发送
  • 客户端发送报文 SYN=1,,序列号Seq 假设为x ( 一般 为1 );
  • 客户端进入同步已发送(SYN_SEND)状态,等待服务器的确认;

建立连接时,客户端发送syn包(syn=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)

第二次握手

  • 服务端收到客户端的SYN报文段,需对这个报文段进行确认 , 设置ack= x+1 (其实是seq值+1 );
  • 同时组织 SYN请求信息,将SYN=1,ACK=1, 随机生成Seq假设为y;
  • 将上述所有信息放到一个报文段(即SYN+ACK报文段)中,发送给客户端,
  • 此时服务器进入同步接收状态(SYN_RECV );

第三次握手

  • 客户端收到服务器的SYN+ACK报文段。
  • 检查 ack number 是否正确,
  • 然后将ACK=1 , seq=x+1, ack=y+1,向服务器发送ACK报文段,
  • 报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED,已建立连接状态,完成TCP三次握手。
  • 三次握手/四次挥

2.TCP 4次挥手

第一次挥手

  • 客户端发送报文,FIN=1,seq=u,此时进入FIN-WAIT-1状态,
    • 即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。

第二次挥手

  • 服务端收到报文,
  • 服务端进入关闭等待状态(CLOSE_WATI),返回一个报文,ACK=1,ack=u+1,seq=v。
  • 客户端收到这个报文之后,直接进入FIN-WAIT-2状态,此时客户端到服务端的连接就释放了。

第三次挥手

  • 服务端发送连接释放报文,FIN=1,ACK=1 , ack=u+1,seq=w,
  • 服务端进入最后确认状态(LAST-ACK),

第四次挥手

  • 客户端收到连接释放报文之后,发应答报文,ACK=1,ack=w+1,seq=u+1,
  • 进入时间等待状态(TIME_WAIT),等待2MSL(即两倍的MSL)后客户端进入关闭状态(CLOSED),
  • 服务端收到报文之后就进入CLOSED状态。
  • 三次握手/四次挥

3.为什么不能2次握手而是要三次握手?

  • TCP是一个双向通信协议,通信双方都有能力发送信息,并接收响应。
  • 为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

具体例子:“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。

4.为什么要四次挥手?

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。

5.为什么三次握手确要四次挥手?

TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,
当客户端发起主动关闭请求FIN 报文,仅仅表示客户端没有数据发送了,但是这个时候还可以接收来自服务端的数据。
需要等待服务端确认向客户端发送数据也完成,才可以关闭。

6.为什么客户端最后还要等待2MSL?

• 客户端需要保证最后一次发送的ACK报文到服务器,如果服务器未收到,可以请求客户端重发,这样客户端还有时间再发,重启2MSL计时。

7.TCP首部的组成

struct tcp_hdr {
  PACK_STRUCT_FIELD(u16_t src);     /* 源端口 */
  PACK_STRUCT_FIELD(u16_t dest);    /* 目的端口 */
  PACK_STRUCT_FIELD(u32_t seqno);   /* 序号 */
  PACK_STRUCT_FIELD(u32_t ackno);   /* 确认序号 */
  PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags);  /* 首部长度+保留位+标志位 */
  PACK_STRUCT_FIELD(u16_t wnd);     /* 窗口大小 */
  PACK_STRUCT_FIELD(u16_t chksum);  /* 校验和 */  
  PACK_STRUCT_FIELD(u16_t urgp);    /* 紧急指针 */
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
上一篇:Wireshark抓包详解-数据包、着色规则和提示


下一篇:Spring整合mybaties -- 注解形式