Linux 网络编程入门
Linux 网络编程是开发者必备技能之一,它基于 TCP/IP 协议栈,通过套接字(Socket)实现进程间的网络通信,本文将介绍 Linux 网络编程的基础概念、核心步骤、常用函数及简单示例,帮助初学者快速入门。

网络编程基础概念
网络编程的核心是套接字(Socket),它是通信的端点,允许不同主机上的进程交换数据,Linux 中,套接字支持多种类型,最常用的是流式套接字(SOCK_STREAM,基于 TCP)和数据报套接字(SOCK_DGRAM,基于 UDP),TCP 提供可靠的面向连接服务,而 UDP 提供无连接的不可靠服务,适用于实时性要求高的场景。
网络通信采用分层模型,如 OSI 七层模型或 TCP/IP 四层模型,Linux 网络编程主要关注应用层,通过调用系统提供的 API(如 socket、bind、listen、connect 等)实现数据收发。
网络编程核心步骤
创建套接字
使用 socket() 函数创建套接字,其原型为:
int socket(int domain, int type, int protocol);
domain:指定地址族,如AF_INET(IPv4)、AF_INET6(IPv6)。type:套接字类型,如SOCK_STREAM(TCP)、SOCK_DGRAM(UDP)。protocol:协议类型,通常设为 0,由系统自动选择。
绑定地址与端口
服务器端需使用 bind() 将套接字与特定 IP 地址和端口绑定:
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockaddr 是通用地址结构,实际使用时需转换为 sockaddr_in(IPv4)或 sockaddr_in6(IPv6)。

监听与连接
服务器调用 listen() 进入监听状态:
int listen(int sockfd, int backlog);
backlog 指定最大待连接队列长度,客户端则通过 connect() 发起连接:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
数据收发
- 接受连接:服务器使用
accept()获取客户端连接,返回新的套接字用于通信。 - 发送数据:
send()或write()向套接字写入数据。 - 接收数据:
recv()或read()从套接字读取数据。
关闭套接字
通信结束后,调用 close() 关闭套接字释放资源:
int close(int sockfd);
关键数据结构与函数
sockaddr_in 结构
用于 IPv4 地址绑定,包含以下字段:
struct sockaddr_in {
short sin_family; // 地址族(AF_INET)
unsigned short sin_port; // 端口号(需转换为网络字节序)
struct in_addr sin_addr; // IP 地址
char sin_zero[8]; // 填充字节
};
sin_addr 是 in_addr 结构,存储 32 位 IP 地址。

字节序转换
网络通信需统一字节序(大端序),使用以下函数转换:
htons():16 位主机序转网络序htonl():32 位主机序转网络序ntohs():16 位网络序转主机序ntohl():32 位网络序转主机序
IP 地址转换
inet_addr() 将点分十进制 IP 转为 32 位无符号长整型,inet_ntoa() 反向转换。
简单示例:TCP 回显服务器
以下是一个基于 TCP 的简单回显服务器,接收客户端消息并原样返回:
#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_fd, client_fd;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建套接字
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 绑定地址与端口
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(server_fd, 3) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d...\n", PORT);
// 接受客户端连接
if ((client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept failed");
exit(EXIT_FAILURE);
}
// 读取客户端消息并回显
int valread = read(client_fd, buffer, BUFFER_SIZE);
printf("Client message: %s\n", buffer);
send(client_fd, buffer, valread, 0);
close(client_fd);
close(server_fd);
return 0;
}
调试与注意事项
- 错误处理:网络编程中需检查所有系统调用的返回值,避免因未处理错误导致程序异常。
- 端口占用:若端口被占用,
bind()会失败,可使用netstat或lsof查看端口使用情况。 - 并发处理:简单示例仅支持单客户端,实际应用需使用多线程或 I/O 多路复用(如
select、epoll)处理多个连接。
学习资源推荐
- 《UNIX 网络编程:套接字联网 API》(经典教材)
- Beej’s Guide to Network Programming(免费在线教程)
- Linux 手册页:
man socket、man bind等
通过掌握上述基础知识和实践,初学者可逐步构建复杂的网络应用,如 HTTP 服务器、聊天程序等,网络编程的核心在于理解协议与 API 的使用,多动手实践是提升技能的关键。



















