1. 网络编程基石:Socket到底是什么?
第一次接触Linux网络编程时,我被各种术语绕得头晕——直到真正用Socket写出能通信的代码,才理解这个抽象概念背后的精妙设计。简单来说,Socket就是进程间通信的"电话插座":两个进程各自创建Socket并建立连接后,就能像打电话一样收发数据。
在Linux系统中,Socket本质上是一种特殊的文件描述符(file descriptor)。当你调用socket()系统调用时,内核会返回一个整数值,这个数字背后对应着内核维护的复杂数据结构,包含协议类型、状态机、缓冲区等关键信息。与普通文件操作不同的是,Socket操作需要处理更多网络特有的问题,比如数据分包、超时重传、流量控制等。
关键理解:Socket API的设计哲学是"一切皆文件"。你可以用
read()/write()操作Socket,就像操作普通文件一样——这种统一性极大简化了编程模型。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Socket核心机制深度解析
2.1 协议族与类型选择
创建Socket时需要明确两个关键参数:
c复制int socket(int domain, int type, int protocol);
-
domain(协议族):决定通信的"语言规则"
AF_INET:IPv4协议(最常用)AF_INET6:IPv6协议AF_UNIX:本地进程间通信
-
type(通信类型):决定数据传输方式
SOCK_STREAM:面向连接的TCP协议(可靠传输)SOCK_DGRAM:无连接的UDP协议(高效传输)
-
protocol:通常设为0,由内核自动选择
实际项目中,90%的场景会使用AF_INET+SOCK_STREAM组合。我曾在一个物联网项目中错误选择了UDP协议,结果因为无线网络丢包导致数据不完整——后来改用TCP才解决问题。这个教训说明:协议选择必须考虑实际网络环境。
2.2 连接建立的三个阶段
TCP Socket通信遵循经典的三次握手流程:
- 服务端准备:
c复制int sockfd = socket(AF_INET, SOCK_STREAM, 0);
