Linux 网络基础与 TCP 协议核心机制
Linux 网络基础与 TCP 协议核心机制。内容涵盖网络协议栈分层、IP 地址与端口定位、常用网络管理工具(ip/ping/ss/tcpdump)。重点解析 TCP 可靠传输的六大机制:三次握手、四次挥手、序号确认重传、滑动窗口流量控制及拥塞控制。对比了 TCP 与 UDP 的特性差异及适用场景,并介绍了 Linux 内核协议栈流转路径及 C++ Socket 编程中的地址封装示例。文章旨在帮助开发者理解网络通信底层逻辑与编程实践。

Linux 网络基础与 TCP 协议核心机制。内容涵盖网络协议栈分层、IP 地址与端口定位、常用网络管理工具(ip/ping/ss/tcpdump)。重点解析 TCP 可靠传输的六大机制:三次握手、四次挥手、序号确认重传、滑动窗口流量控制及拥塞控制。对比了 TCP 与 UDP 的特性差异及适用场景,并介绍了 Linux 内核协议栈流转路径及 C++ Socket 编程中的地址封装示例。文章旨在帮助开发者理解网络通信底层逻辑与编程实践。

数据在网络中的传输遵循分层协作模型,各层职责明确:
在 Socket 网络编程(IPv4 场景)中,sockaddr_in结构体的 sin_addr字段以 32 位二进制形式存储 IP 地址。日常习惯用点分十进制字符串表示,因此需要借助地址转换函数实现互转。
需引入头文件 <arpa/inet.h>,常用函数包括:
inet_pton(int family, const char *strptr, void *addrptr):通用函数,支持 IPv4/IPv6。将字符串转为二进制地址存入 addrptr。inet_ntop(int family, const void *addrptr, char *strptr, size_t len):更安全的通用函数,需手动传入缓冲区,避免线程安全问题。注意:
inet_ntoa返回静态缓冲区,多线程下可能被覆盖,建议优先使用inet_ntop。
发送方流程:
接收方反向操作:拆帧→拆数据报→拆报文段→获取原始数据。
IP 地址定位主机,端口号定位主机上的进程。"IP+ 端口"构成唯一通信端点。
| 工具 | 核心功能 | 常用命令示例 |
|---|---|---|
| ip addr | 查看/配置 IP 地址 | ip addr add 192.168.1.100/24 dev eth0 |
| ip route | 查看/配置路由表 | ip route add default via 192.168.1.1 |
| ping | 测试主机连通性 | ping -c 4 www.baidu.com |
| ss/netstat | 查看网络连接状态 | ss -tulnp |
| tcpdump | 网络抓包分析 | tcpdump -i eth0 port 80 |
TCP 是互联网的核心协议,通过六大机制保证数据不丢、不错、不乱。
由固定头部(20 字节)+ 选项 + 数据组成。核心字段包括序号/确认号(可靠性)、窗口大小(流量控制)、标志位(SYN/ACK/FIN/RST)。
建立连接需三次交互以确认双方收发能力:
TCP 全双工通信,关闭需分两步:
注意:主动方最后进入 TIME_WAIT 状态,等待 60 秒防止最后一个 ACK 丢失。
接收方通过窗口大小告知发送方可接收的数据量,防止缓冲区溢出。
根据网络状况调整发送速率,核心为拥塞窗口(cwnd):
| 特性 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接 | 无连接 |
| 可靠性 | 可靠(重传、确认) | 不可靠 |
| 有序性 | 保证有序 | 不保证有序 |
| 速度 | 较慢 | 快 |
| 适用场景 | HTTP、MySQL、支付 | 直播、游戏、DNS |
应用程序通过 socket 接口调用内核处理 TCP/IP 细节。
应用程序 → socket 层 → inet 层 → IP 层 → 数据链路层 → 网卡。
以下 InetAddr 类展示了 IP 与端口的封装处理:
#include <arpa/inet.h>
#include <string>
#include <cstdint>
class InetAddr {
public:
// 从 sockaddr_in(网络字节序)初始化
InetAddr(const struct sockaddr_in& addr) {
_addr = addr;
_port = ntohs(addr.sin_port);
_ip = inet_ntoa(addr.sin_addr);
}
// 从 IP 字符串和端口(主机序)初始化
InetAddr(const std::string& ip, uint16_t port) {
memset(&_addr, 0, sizeof(_addr));
_addr.sin_family = AF_INET;
_addr.sin_port = htons(port);
inet_pton(AF_INET, ip.c_str(), &_addr.sin_addr);
_ip = ip;
_port = port;
}
uint16_t Port() const { return _port; }
std::string Ip() const { return _ip; }
const struct sockaddr_in& GetSockAddr() const { return _addr; }
private:
struct sockaddr_in _addr;
std::string _ip;
uint16_t _port;
};
跨平台提示:Windows 平台需引入 WinSock2.h 并链接 ws2_32.lib,且需调用 WSAStartup 初始化套接字库,Linux 无需此步骤。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online