Linux网络编程核心流程解析
Linux网络编程的核心在于使用Socket API在TCP/IP协议栈基础上实现进程间网络通信。其核心流程围绕创建Socket、绑定地址、建立连接、数据传输、关闭连接展开并因协议TCP/UDP和I/O模型的不同而有显著差异。一、核心概念与协议特性TCP (传输控制协议)UDP (用户数据报协议)连接性面向连接需三次握手建立连接无连接可靠性可靠提供确认、重传、排序、流量控制不可靠尽最大努力交付数据形式字节流无边界数据报有边界速度相对较慢相对较快应用场景文件传输、Web浏览、邮件要求可靠视频流、DNS查询、广播要求实时Socket类型SOCK_STREAMSOCK_DGRAM二、Socket编程核心函数与流程1. TCP服务器端典型流程并发迭代式#include sys/socket.h #include netinet/in.h #include arpa/inet.h #include unistd.h #include string.h int main() { // 1. 创建Socket (TCP) int server_fd socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // if (server_fd -1) { /* 错误处理 */ } // 2. 设置Socket选项避免地址占用错误 int opt 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt)); // // 3. 绑定地址和端口 struct sockaddr_in server_addr; memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; // IPv4 server_addr.sin_addr.s_addr INADDR_ANY; // 监听所有网卡 server_addr.sin_port htons(8080); // 端口转换为网络字节序 if (bind(server_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { /* 错误处理 */ } // 4. 监听连接请求 if (listen(server_fd, 10) -1) { // 第二个参数为等待队列长度 /* 错误处理 */ } printf(TCP Server listening on port 8080... ); while(1) { // 5. 接受客户端连接 struct sockaddr_in client_addr; socklen_t client_len sizeof(client_addr); int client_fd accept(server_fd, (struct sockaddr*)client_addr, client_len); // if (client_fd -1) { continue; // 接受失败继续循环 } // 6. 处理连接例如fork子进程或创建线程 // 此处为简单示例直接在主进程处理 char buffer[1024]; ssize_t num_bytes read(client_fd, buffer, sizeof(buffer)-1); if (num_bytes 0) { buffer[num_bytes] \0; printf(Received: %s , buffer); write(client_fd, Hello from TCP Server!, 22); } // 7. 关闭客户端Socket close(client_fd); } // 8. 关闭服务器Socket (实际不会执行到这里) close(server_fd); return 0; }2. TCP客户端典型流程#include sys/socket.h #include netinet/in.h #include arpa/inet.h #include unistd.h #include string.h #include stdio.h int main() { // 1. 创建Socket int sock_fd socket(AF_INET, SOCK_STREAM, 0); // 2. 准备服务器地址 struct sockaddr_in server_addr; server_addr.sin_family AF_INET; server_addr.sin_port htons(8080); inet_pton(AF_INET, 127.0.0.1, server_addr.sin_addr); // 将点分十进制IP转为网络字节序 // 3. 连接服务器 if (connect(sock_fd, (struct sockaddr*)server_addr, sizeof(server_addr)) -1) { perror(Connect failed); return -1; } // 4. 发送数据 char *message Hello TCP Server!; send(sock_fd, message, strlen(message), 0); // 5. 接收数据 char buffer[1024]; ssize_t num_bytes recv(sock_fd, buffer, sizeof(buffer)-1, 0); if (num_bytes 0) { buffer[num_bytes] \0; printf(Server replied: %s , buffer); } // 6. 关闭Socket close(sock_fd); return 0; }3. UDP服务器/客户端流程无连接UDP通信中服务器端无需listen()和accept()客户端也无需connect()。双方都使用sendto()和recvfrom()函数在每次收发数据时指定对端地址。// UDP 服务器端核心代码示例 int sock_fd socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // struct sockaddr_in server_addr, client_addr; // ... 绑定(bind)地址 ... while(1) { socklen_t client_len sizeof(client_addr); // 接收数据同时获取客户端地址 ssize_t num_bytes recvfrom(sock_fd, buffer, sizeof(buffer), 0, (struct sockaddr*)client_addr, client_len); // 处理数据... // 发送数据回客户端使用recvfrom获取的地址 sendto(sock_fd, response, strlen(response), 0, (struct sockaddr*)client_addr, client_len); }三、关键技术与高级主题1. I/O多路复用解决C10K问题当需要同时处理大量连接时循环阻塞处理如上例效率极低。I/O多路复用允许单个线程监控多个文件描述符Socket的就绪状态。模型描述特点select跨平台监控描述符集合有文件描述符数量限制通常1024效率随描述符增多线性下降poll改进的select使用链表存储无硬性数量限制但效率问题同selectepoll(Linux特有)事件驱动仅通知就绪描述符高效支持边缘触发(ET)和水平触发(LT)适合高并发epoll 使用示例#include sys/epoll.h // 创建epoll实例 int epoll_fd epoll_create1(0); struct epoll_event ev, events[MAX_EVENTS]; // 将监听socket加入epoll监控 ev.events EPOLLIN; // 监控可读事件 ev.data.fd server_fd; epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, ev); while(1) { // 等待事件发生 int nfds epoll_wait(epoll_fd, events, MAX_EVENTS, -1); for(int i 0; i nfds; i) { if(events[i].data.fd server_fd) { // 有新连接 int client_fd accept(server_fd, ...); ev.events EPOLLIN | EPOLLET; // 边缘触发模式 ev.data.fd client_fd; epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, ev); } else { // 已连接socket有数据可读 handle_client_data(events[i].data.fd); } } }2. 地址与字节序转换网络字节序统一使用大端序。主机字节序可能是小端序需转换。#include arpa/inet.h uint32_t htonl(uint32_t hostlong); // 主机到网络 (长整型) uint16_t htons(uint16_t hostshort); // 主机到网络 (短整型) uint32_t ntohl(uint32_t netlong); // 网络到主机 uint16_t ntohs(uint16_t netshort); // 点分十进制IP地址与二进制网络地址互转 int inet_pton(int af, const char *src, void *dst); // 字符串-二进制 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); // 二进制-字符串3. TCP粘包与拆包处理TCP是字节流协议发送的多个数据包可能在接收缓冲区中被合并粘包或拆分。解决方案包括定长消息所有消息固定长度。分隔符使用特殊字符如分隔消息。长度前缀在消息头部添加固定长度的字段表示消息体长度常用。长度前缀法示例// 发送端 uint32_t msg_len htonl(strlen(actual_message)); // 转换为网络字节序 send(sock_fd, msg_len, sizeof(msg_len), 0); // 先发送长度 send(sock_fd, actual_message, strlen(actual_message), 0); // 再发送数据 // 接收端 uint32_t msg_len_net; recv(sock_fd, msg_len_net, sizeof(msg_len_net), MSG_WAITALL); uint32_t msg_len_host ntohl(msg_len_net); // 转换为主机字节序 char *buffer malloc(msg_len_host 1); recv(sock_fd, buffer, msg_len_host, MSG_WAITALL); buffer[msg_len_host] \0;4. Socket选项设置使用setsockopt()函数可配置Socket行为。// 设置地址重用防止重启服务器时“Address already in use”错误 int reuse 1; setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, reuse, sizeof(reuse)); // // 设置接收超时 struct timeval timeout; timeout.tv_sec 5; timeout.tv_usec 0; setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, timeout, sizeof(timeout));四、常见网络编程模型对比模型描述优点缺点适用场景阻塞I/O 多进程/线程每个连接分配一个进程/线程编程简单逻辑清晰资源消耗大上下文切换开销高连接数较少1000I/O多路复用 (select/poll)单线程轮询多个连接资源占用少可处理更多连接效率随连接数线性下降编程复杂中等并发跨平台要求I/O多路复用 (epoll)事件驱动回调通知高效可处理数万乃至数十万连接Linux特有编程复杂Linux下高并发服务器异步I/O (AIO)内核完成I/O后通知应用理论上性能最高实现复杂生态不成熟特定高性能场景五、调试与工具netstat/ss: 查看网络连接、监听端口、路由表等信息。tcpdump/Wireshark: 抓取和分析网络数据包。strace: 跟踪系统调用排查程序行为。nc(netcat): 网络调试的瑞士军刀可模拟TCP/UDP客户端/服务器。参考来源【linux 之网络编程socket tcp udp 超详细讲解】Linux网络编程2024超级详细、Linux【Linux】Linux网络编程思维导图C教程网之Linux网络编程视频 Unix网络编程视频54.Linux 网络编程

相关新闻

【会议征稿通知 | 桂林电子科技大学主办 | ACM出版 | EI 、Scopus稳定检索】第二届生成式AI与数字媒体艺术国际学术会议 (GAIDMA 2026)

【会议征稿通知 | 桂林电子科技大学主办 | ACM出版 | EI 、Scopus稳定检索】第二届生成式AI与数字媒体艺术国际学术会议 (GAIDMA 2026)

第二届生成式AI与数字媒体艺术国际学术会议 (GAIDMA 2026) 2026 2nd International Conference on Generative AI and Digital Media Arts 2026年9月18-20日 | 中国-桂林 大会官网:www.gaidma.net 截稿时间:见官网(…

2026/11/13 14:08:58 阅读更多 →
《我的世界》基岩版Mod开发入门:从零创建空白附加包

《我的世界》基岩版Mod开发入门:从零创建空白附加包

1. 项目概述:从玩家到创造者的第一步 如果你和我一样,在《我的世界》里从撸树挖矿开始,逐渐不满足于原版世界的规则,总想加点“私货”——比如让苦力怕爆炸后掉落钻石,或者给自己做一把能发射闪电的超级镐子——那么&a…

2026/11/12 17:55:00 阅读更多 →
靠别Delay,按键边沿检测与消抖分享

靠别Delay,按键边沿检测与消抖分享

引言:本人是桂林电子科技大学测控专业大四学生,结合蓝桥杯单片机国奖备赛与参赛经验做技术复盘。本文基于竞赛常用的STC15F2K60S2 单片机、Keil IDE,C 语言环境,针对赛题高频考点机械按键处理展开讲解。详解延时、定时扫描、计数器消抖三种软…

2026/10/25 7:36:34 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻