Linux 网络基础与 TCP 协议核心解析
一、网络通信的底层逻辑:协议栈与封装
在浏览器输入网址,数据是如何传输到服务器的?答案在于'分层协作'。这就像快递系统:应用层负责打包(定格式),传输层贴地址(标进程),网络层选路线(标主机),物理层负责运输。每一层各司其职,互不越界。
1. Linux 网络协议栈分层
- 应用层:给数据定格式,如 HTTP、SSH、FTP。
- 传输层:给数据标进程,通过端口号区分同一台电脑上的不同程序(80 端口通常是浏览器,3306 是 MySQL),核心协议是 TCP 和 UDP。
- 网络层:给数据标主机,用 IP 地址定位目标设备。
- 数据链路层:给数据标节点,用 MAC 地址在局域网内传输。
- 物理层:纯硬件传输,如网线传电信号、光纤传光信号。
在 Socket 网络编程(IPv4 场景)中,sockaddr_in结构体的 sin_addr字段以 32 位二进制形式存储 IP 地址,但日常习惯使用点分十进制字符串(如 192.168.1.1)。因此需要借助地址转换函数实现两种格式的互转,这是绑定 IP、解析地址的基础操作。
地址转换函数
需引入头文件 <arpa/inet.h>,常用函数包括:
- inet_pton:更通用的函数(支持 IPv4/IPv6),将字符串转为二进制地址存入指定指针。推荐优先使用此函数替代旧版接口。
- inet_ntop:将二进制地址转为可读字符串,需手动传入缓冲区,避免线程安全问题。
相比之下,inet_aton 和 inet_ntoa 虽然经典,但在多线程或复杂场景下存在局限性。例如 inet_ntoa 返回的是静态缓冲区,多次调用可能导致结果被覆盖。

2. 数据封装与解封装
发送数据时,各层依次添加头部信息:
- 应用层:生成原始数据。
- 传输层:加头,包含源端口和目的端口,形成报文段。
- 网络层:加头,包含源 IP 和目标 IP,形成数据报。
- 数据链路层:加头和尾,包含源 MAC 和目的 MAC,形成以太网帧。
- 物理层:将帧转换为电信号发出。
接收方则反向操作:拆帧→拆数据报→拆报文段→拿到原始数据。
在 C++ 网络编程中,通常会封装一个 InetAddr 类来处理 IP 与端口的转换逻辑,统一字节序处理。
#include <arpa/inet.h>
#include <string>
#include <cstdint>
{
:
( sockaddr_in& addr) : _addr(addr) {
_port = (addr.sin_port);
_ip = (addr.sin_addr);
}
( std::string& ip, port) : _ip(ip), _port(port) {
(&_addr, , (_addr));
_addr.sin_family = AF_INET;
_addr.sin_port = (port);
(AF_INET, ip.(), &_addr.sin_addr);
}
{ _port; }
{ _ip; }
& () { _addr; }
:
_addr;
std::string _ip;
_port;
};







