菜鸟-创作你的创作

Linux 网络编程:传输层 TCP(一)—— TCP 基础与连接管理

Linux 网络编程:传输层 TCP(一)—— TCP 基础与连接管理

在 Linux 网络编程中,传输层协议主要包括 TCP(Transmission Control Protocol)UDP(User Datagram Protocol)。其中 TCP 是互联网最常用的传输协议之一,广泛应用于 Web、数据库、邮件、文件传输等场景。

本篇将详细介绍 TCP 的基本概念、特点、报文格式、三次握手与四次挥手,为后续 Socket 编程打下基础。


一、什么是 TCP?

TCP(Transmission Control Protocol,传输控制协议)是一种:

的传输层协议。

位于 TCP/IP 协议栈中的传输层:

应用层
  ↓
HTTP、FTP、SMTP
  ↓
TCP
  ↓
IP
  ↓
数据链路层
  ↓
物理层


二、TCP 的特点

1. 面向连接

通信双方在传输数据前必须先建立连接。

类似于:

打电话
↓
拨号
↓
接通
↓
开始聊天

TCP 也是如此:

客户端
↓
建立连接
↓
服务端
↓
数据传输


2. 可靠传输

TCP 保证:

实现机制:


3. 面向字节流

TCP 不关心数据边界。

例如:

客户端:

send(sock,"Hello",5,0);
send(sock,"World",5,0);

服务端:

可能收到:

HelloWorld

也可能:

Hel
loWorld

因此:

TCP没有消息边界

应用层需要自行处理数据包边界问题。


4. 全双工通信

客户端和服务端可同时发送和接收数据。

例如:

客户端 ←→ 服务端

双方互不影响。


三、TCP 与 UDP 对比

特性TCPUDP
是否连接
是否可靠
是否排序保证不保证
是否重传支持不支持
传输速度较慢较快
头部大小20~60字节8字节
应用场景Web、数据库视频、直播、游戏

四、TCP 报文段结构

TCP 首部最小:

20字节

结构如下:

 0                   15 16                  31
+----------------------+----------------------+
|     源端口           |     目标端口         |
+----------------------+----------------------+
|            序列号 Sequence Number           |
+---------------------------------------------+
|            确认号 Acknowledgment Number      |
+---------------------------------------------+
|头长|保留|控制位|         窗口大小           |
+---------------------------------------------+
|      校验和          |      紧急指针         |
+---------------------------------------------+
|              选项 Option                    |
+---------------------------------------------+


五、重要字段详解

1. 源端口

发送方端口。

例如:

52345


2. 目标端口

接收方端口。

例如:

80
443
3306


3. 序列号(SEQ)

TCP 为每个字节编号。

例如:

Seq = 1000

表示:

从1000开始发送数据

用于:


4. 确认号(ACK)

表示:

已经收到的数据

例如:

ACK = 2000

说明:

1999之前的数据都收到了

下一次请发送:

2000

之后的数据。


六、TCP 控制位(Flags)

TCP 有六个核心标志位:

标志位含义
SYN建立连接
ACK确认
FIN关闭连接
RST重置连接
PSH推送数据
URG紧急数据

七、三次握手(Three-Way Handshake)

TCP 建立连接时需要三次握手。


为什么需要三次?

目的:

确认:

客户端发送能力
客户端接收能力
服务端发送能力
服务端接收能力

均正常。


第一次握手

客户端:

SYN=1
Seq=x

发送:

我要建立连接

状态:

SYN_SENT


第二次握手

服务端收到:

返回:

SYN=1
ACK=1
Seq=y
Ack=x+1

表示:

收到你的请求
我也同意建立连接

状态:

SYN_RCVD


第三次握手

客户端收到:

再次发送:

ACK=1
Ack=y+1

表示:

收到你的确认
连接建立成功

状态:

ESTABLISHED

服务端收到后:

ESTABLISHED


三次握手过程图

客户端                         服务端

   SYN=x
  ----------->
                    

          SYN=y ACK=x+1
  <-----------

   ACK=y+1
  ----------->

连接建立成功


八、为什么不是两次握手?

假设:

客户端发送:

SYN

由于网络延迟:

很久以后才到达服务端

客户端早已放弃。

如果仅两次握手:

服务端会误认为:

客户端仍然需要连接

从而建立无效连接。

第三次握手的作用:

确认客户端确实收到服务端响应

避免历史连接请求造成资源浪费。


九、Linux 查看三次握手

抓包:

sudo tcpdump -i eth0 tcp

或者:

sudo tcpdump -i any port 80

典型输出:

S
S.
.

含义:

S   -> SYN
S.  -> SYN+ACK
.   -> ACK


十、四次挥手(Four-Way Handshake)

TCP 是全双工通信。

双方都要独立关闭。

因此需要:

四次挥手


第一次挥手

客户端:

FIN=1

表示:

我没有数据发送了

状态:

FIN_WAIT_1


第二次挥手

服务端:

ACK

表示:

收到关闭请求

状态:

CLOSE_WAIT

客户端进入:

FIN_WAIT_2


第三次挥手

服务端处理完剩余数据:

发送:

FIN

表示:

我也关闭

状态:

LAST_ACK


第四次挥手

客户端:

ACK

回复。

状态:

TIME_WAIT

服务端:

CLOSED


四次挥手过程图

客户端                         服务端

FIN
--------->

        ACK
<---------

        FIN
<---------

ACK
--------->


十一、TIME_WAIT 状态

很多开发者会发现:

netstat -ant

输出:

TIME_WAIT

大量存在。


为什么需要 TIME_WAIT?

保证:

最后一个 ACK
能够成功到达

如果 ACK 丢失:

服务端会重发:

FIN

客户端还能处理。


TIME_WAIT 时长

Linux:

2MSL

通常:

60秒左右

查看:

cat /proc/sys/net/ipv4/tcp_fin_timeout


十二、TCP 状态转换图

常见状态:

LISTEN
↓
SYN_RCVD
↓
ESTABLISHED
↓
FIN_WAIT_1
↓
FIN_WAIT_2
↓
TIME_WAIT
↓
CLOSED

服务端:

LISTEN
↓
SYN_RCVD
↓
ESTABLISHED
↓
CLOSE_WAIT
↓
LAST_ACK
↓
CLOSED


十三、Linux 查看 TCP 状态

查看连接:

ss -ant

或者:

netstat -ant

示例:

LISTEN
ESTAB
TIME_WAIT
CLOSE_WAIT

查看统计:

ss -s

输出:

TCP:
estab 15
closed 230
timewait 40


十四、面试高频问题

TCP 为什么可靠?

答:


为什么是三次握手?

为了确认:

并防止历史连接请求造成错误连接。


为什么是四次挥手?

TCP 全双工。

双方关闭发送通道需要分别通知,因此需要四次。


TIME_WAIT 为什么存在?

保证:

避免影响新的连接。


总结

TCP 是 Linux 网络编程中最重要的传输层协议之一,其核心特征包括:

重点掌握:

  1. TCP 报文结构
  2. 序列号与确认号
  3. 六大控制位
  4. 三次握手建立连接
  5. 四次挥手断开连接
  6. TIME_WAIT 状态原理

理解这些基础知识后,学习 socket()bind()listen()accept()connect() 等 Linux Socket API 时会更加容易。下一篇通常会深入 TCP 的可靠传输机制,包括滑动窗口、流量控制、拥塞控制和重传机制。

退出移动版