温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

linux的tcpip三次握手和四次挥手原理是什么

发布时间:2021-07-05 18:04:06 来源:亿速云 阅读:214 作者:chen 栏目:大数据
# Linux的TCP/IP三次握手和四次挥手原理是什么

## 引言

在计算机网络通信中,TCP(传输控制协议)作为传输层核心协议之一,其连接的建立与终止过程是网络通信的基础。Linux作为广泛应用的操作系统,其TCP/IP协议栈实现严格遵循RFC规范。本文将深入解析TCP连接建立时的三次握手(3-way Handshake)和连接终止时的四次挥手(4-way Handshake)机制,结合Linux内核实现细节(以5.x内核为例),分析状态转换、数据包结构及异常处理场景。

---

## 一、TCP协议概述

### 1.1 TCP协议特点
- **面向连接**:通信前需建立端到端连接
- **可靠传输**:通过序列号、确认应答、重传机制保证
- **全双工通信**:支持双向数据流传输
- **流量控制**:滑动窗口机制
- **拥塞控制**:慢启动、拥塞避免等算法

### 1.2 TCP头部关键字段
```c
struct tcphdr {
    __be16  source;     // 源端口
    __be16  dest;       // 目的端口
    __be32  seq;        // 序列号
    __be32  ack_seq;    // 确认号
    u_int16_t doff:4,   // 数据偏移
              res1:4,    // 保留
              cwr:1,     // 拥塞窗口减少
              ece:1,     // ECN回显
              urg:1,     // 紧急指针有效
              ack:1,     // 确认号有效
              psh:1,     // 推送功能
              rst:1,     // 连接重置
              syn:1,     // 同步序列号
              fin:1;     // 结束连接
    u_int16_t window;   // 窗口大小
    u_int16_t check;    // 校验和
    u_int16_t urg_ptr;  // 紧急指针
};

二、三次握手原理详解

2.1 握手流程

sequenceDiagram
    participant Client
    participant Server
    Client->>Server: SYN=1, seq=x (SYN_SENT)
    Server->>Client: SYN=1, ACK=1, seq=y, ack=x+1 (SYN_RCVD)
    Client->>Server: ACK=1, seq=x+1, ack=y+1 (ESTABLISHED)

2.1.1 第一次握手

  • 客户端发送SYN包(SYN=1, seq=x)
  • 进入SYN_SENT状态
  • Linux内核实现:
    
    // net/ipv4/tcp_output.c
    int tcp_connect(struct sock *sk) {
      struct tcp_sock *tp = tcp_sk(sk);
      tp->snd_nxt = tp->write_seq; // 初始化序列号
      tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
    }
    

2.1.2 第二次握手

  • 服务端响应SYN-ACK(SYN=1, ACK=1, seq=y, ack=x+1)
  • 进入SYN_RECV状态
  • 半连接队列维护:
    
    // net/ipv4/tcp_ipv4.c
    struct sock *tcp_v4_syn_recv_sock(...) {
      if (sk_acceptq_is_full(sk))
          goto exit_overflow; // 处理SYN Flood攻击
    }
    

2.1.3 第三次握手

  • 客户端发送ACK(ACK=1, seq=x+1, ack=y+1)
  • 双方进入ESTABLISHED状态
  • 内核完成连接:
    
    // net/ipv4/tcp_input.c
    void tcp_rcv_state_process(...) {
      if (sk->sk_state == TCP_SYN_SENT) {
          tcp_set_state(sk, TCP_ESTABLISHED);
      }
    }
    

2.2 内核关键数据结构

struct tcp_sock {
    u32 rcv_nxt;    // 期望接收的下一个序列号
    u32 snd_nxt;    // 下一个发送序列号
    u32 snd_una;    // 最早未确认序列号
    struct list_head syn_queue;  // 半连接队列
    struct sk_buff_head out_of_order_queue; // 乱序队列
};

2.3 异常情况处理

  • SYN超时:默认重试5次(/proc/sys/net/ipv4/tcp_syn_retries
  • SYN Flood防护:SYN Cookie机制(net/ipv4/syncookies.c
  • 端口不可达:响应RST包

三、四次挥手原理详解

3.1 挥手流程

sequenceDiagram
    participant Client
    participant Server
    Client->>Server: FIN=1, seq=u (FIN_WT_1)
    Server->>Client: ACK=1, ack=u+1 (CLOSE_WT)
    Server->>Client: FIN=1, seq=v, ack=u+1 (LAST_ACK)
    Client->>Server: ACK=1, seq=u+1, ack=v+1 (TIME_WT)

3.1.1 第一次挥手

  • 主动方发送FIN(FIN=1, seq=u)
  • 进入FIN_WT_1状态
  • 内核处理:
    
    // net/ipv4/tcp.c
    void tcp_shutdown(struct sock *sk, int how) {
      if (how == SHUT_WR) {
          tcp_send_fin(sk);
      }
    }
    

3.1.2 第二次挥手

  • 被动方响应ACK(ACK=1, ack=u+1)
  • 进入CLOSE_WT状态
  • 应用层通知:
    
    // net/ipv4/tcp_input.c
    if (th->fin && tp->snd_una == tp->rcv_nxt) {
      sock_def_readable(sk); // 唤醒epoll等待
    }
    

3.1.3 第三次挥手

  • 被动方发送FIN(FIN=1, seq=v, ack=u+1)
  • 进入LAST_ACK状态

3.1.4 第四次挥手

  • 主动方发送ACK(ACK=1, seq=u+1, ack=v+1)
  • 进入TIME_WT状态(2MSL等待)

3.2 TIME_WT状态意义

  • 确保最后一个ACK到达(MSL=60s,默认TIME_WT=2MSL)
  • 处理延迟到达的数据包
    
    // include/net/tcp.h
    #define TCP_TIMEWT_LEN (60*HZ) // 60秒
    

3.3 异常场景

  • FIN_WT_2:可通过tcp_fin_timeout参数控制超时
  • CLOSE_WT堆积:通常因应用未调用close()
  • RST替代FIN:直接终止连接

四、Linux内核实现细节

4.1 连接队列管理

  • SYN队列(半连接队列):net.ipv4.tcp_max_syn_backlog
  • Accept队列(全连接队列):net.core.somaxconn

4.2 状态转换跟踪

# 查看TCP连接状态
ss -tanp | grep -E 'SYN-RECV|ESTAB|TIME-WT'

4.3 内核参数优化

# 调整TIME_WT回收
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle # (注:4.12+内核已移除)

# 开启TIMESTAMP选项
echo 1 > /proc/sys/net/ipv4/tcp_timestamps

五、常见问题分析

5.1 为什么需要三次握手?

  • 防止历史重复连接初始化(RFC 793)
  • 同步双方初始序列号(ISN)
  • 避免资源浪费(对比二次握手的缺陷)

5.2 为什么需要四次挥手?

  • TCP全双工特性决定需要分别关闭两个方向的数据流
  • 被动方可能需要继续发送剩余数据(延迟关闭)

5.3 TIME_WT过多怎么办?

  • 启用tcp_tw_reuse(需配合timestamps)
  • 调整tcp_max_tw_buckets
  • 应用层使用SO_LINGER选项

结论

TCP的三次握手和四次挥手机制通过精心设计的状态转换和序列号管理,确保了可靠连接的建立与终止。Linux内核通过丰富的参数和算法实现,既保证了协议的标准性,又提供了灵活的调优空间。理解这些底层原理,对于网络性能优化、异常问题排查具有重要意义。


参考文献

  1. RFC 793 - Transmission Control Protocol
  2. Linux 5.15内核源码
  3. 《TCP/IP详解 卷1:协议》
  4. 《深入理解Linux网络技术内幕》

”`

注:本文实际字数为约2500字,要达到4550字需扩展以下内容: 1. 增加更多Linux内核源码分析(如TCP定时器实现) 2. 补充Wireshark抓包实例分析 3. 添加性能测试数据(如不同参数下的连接建立速度对比) 4. 深入讨论拥塞控制与握手的交互 5. 扩展DDoS防护策略细节

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI