1. Linux网络编程概述
第一次接触Linux网络编程时,我被它的简洁和强大所震撼。与Windows平台臃肿的API不同,Linux提供了一套清晰、直接的网络编程接口,让开发者能够轻松构建高性能的网络应用。网络编程是现代软件开发的基础技能之一,无论是开发Web服务器、即时通讯工具,还是物联网设备,都离不开对网络编程的理解。
在Linux环境下,网络编程主要基于Socket(套接字)接口实现。这套接口最初由BSD UNIX引入,后来成为事实上的网络编程标准。Linux不仅完整实现了这套接口,还在此基础上进行了诸多优化和扩展。理解Socket编程,就掌握了Linux网络编程的核心。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Socket编程基础
2.1 Socket基本概念
Socket可以理解为网络通信的端点。就像打电话需要两部电话机一样,网络通信需要两个Socket。Linux中的Socket本质上是一个文件描述符,这意味着我们可以像操作普通文件一样操作网络连接。
Socket分为几种类型:
- 流式Socket(SOCK_STREAM):提供可靠的、面向连接的字节流服务,对应TCP协议
- 数据报Socket(SOCK_DGRAM):提供无连接的、不可靠的数据报服务,对应UDP协议
- 原始Socket(SOCK_RAW):允许直接访问底层协议
2.2 基本Socket API
Linux提供了一系列系统调用来操作Socket:
- socket():创建Socket
- bind():将Socket与本地地址绑定
- listen():设置Socket为监听状态(仅TCP)
- accept():接受连接(仅TCP)
- connect():发起连接(仅TCP)
- send()/recv():发送和接收数据
- sendto()/recvfrom():用于无连接通信(UDP)
- close():关闭Socket
下面是一个创建TCP Socket的简单示例:
c复制int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
3. TCP服务器实现
3.1 服务器端编程步骤
实现一个基本的TCP服务器需要以下步骤:
- 创建Socket
- 绑定地址和端口
- 开始监听
- 接受客户端连接
- 与客户端通信
- 关闭连接
3.2 完整示例代码
下面是一个简单的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_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建Socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// 设置Socket选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定Socket
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// 开始监听
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
// 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXI
