1. Linux网络套接字编程概述
在Linux环境下进行网络编程,套接字(socket)是最基础也是最核心的接口。它就像计算机网络世界的"万能插座",允许不同主机上的进程通过TCP/IP协议栈进行数据交换。我最早接触socket编程是在开发一个分布式日志收集系统时,需要让多台服务器将日志实时传输到中央节点进行分析。当时踩了不少坑,但也积累了不少实战经验。
套接字编程本质上是通过操作系统提供的系统调用来创建、配置和管理网络连接。在Linux中,一切皆文件的思想也体现在socket上——每个socket连接都被抽象为一个文件描述符,可以使用read/write等文件操作函数进行数据传输。这种设计极大简化了网络编程的复杂度。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心概念与协议选择
2.1 TCP vs UDP协议选择
TCP(传输控制协议)和UDP(用户数据报协议)是socket编程中最常用的两种传输层协议。选择哪种协议取决于你的应用场景:
-
TCP:面向连接、可靠传输、保证顺序。适合需要数据完整性的场景,如文件传输、网页访问等。建立连接需要三次握手,断开需要四次挥手,有一定的性能开销。
典型代码结构:
c复制// 服务器端 socket() -> bind() -> listen() -> accept() -> read()/write() -> close() // 客户端 socket() -> connect() -> read()/write() -> close() -
UDP:无连接、不可靠但速度快。适合实时性要求高的场景,如视频会议、在线游戏等。数据包可能丢失或乱序,需要应用层自己处理。
典型代码结构:
c复制// 收发双方 socket() -> bind()(可选) -> sendto()/recvfrom() -> close()
经验提示:新手常犯的错误是试图用UDP实现可靠传输。实际上如果需要可靠性,应该直接使用TCP,或者在应用层实现确认重传机制。
2.2 套接字地址结构
Linux提供了几种socket地址结构,最常用的是:
c复制struct sockaddr_in {
sa_family_t sin_family; // 地址族,如AF_INET
in_port_t sin_port; // 端口号(网络字节序)
struct in_addr sin_addr; // IP地址
};
struct in_addr {
uint32_t s_addr; // 32位IPv4地址(网络字节序)
};
使用时需要特别注意字节序问题。Intel CPU使用小端字节序,而网络协议使用大端字节序,因此需要用htons()、htonl()等函数进行转换。
3. TCP套接字编程实战
3.1 基础服务器实现
下面是一个最简单的TCP回显服务器实现:
c复制#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_
