当前位置: 首页 > news >正文

Linux网络编程基础(UDP socket编程)

UDP用户数据报协议是一种无连接的传输层协议与TCP不同它不保证数据包的顺序和可靠性但其简单性和低延迟特性使其在实时应用中非常有用。一、UDP协议核心特性UDP作为传输层协议与TCP的“可靠连接”不同它具有以下特点无连接通信前无需建立三次握手直接发送数据报不可靠不保证数据有序到达也不重传丢失的数据包面向数据报数据以固定大小的“数据报”为单位传输低延迟省去连接建立和确认机制适合实时场景如聊天、直播UDP适合用于一次传送少量数据、对可靠性要求不高的应用环境。例如流媒体、在线游戏、DNS查询等场景。二、UDP编程模型UDP是无连接的先启动哪一端都不会报错。UDP编程与TCP的核心差异在于“无连接”特性——无需listen、accept、connect流程直接通过sendto与recvfrom完成数据收发。服务器端流程创建套接字使用socket(AF_INET, SOCK_DGRAM, 0)创建UDP套接字绑定地址使用bind()将套接字与IP地址和端口号关联收发数据使用recvfrom()/sendto()进行数据交互关闭套接字使用close()释放资源客户端流程创建套接字使用socket(AF_INET, SOCK_DGRAM, 0)创建UDP套接字收发数据使用sendto()/recvfrom()进行数据交互关闭套接字使用close()释放资源三、核心API函数详解1. socket() - 创建套接字int sockfd socket(AF_INET, SOCK_DGRAM, 0);AF_INETIPv4协议族SOCK_DGRAM数据报套接字对应UDP协议区别于TCP的SOCK_STREAM第三个参数通常设为0表示由内核自动选择协议2. bind() - 绑定地址服务器端必须UDP服务器端必须调用bind函数将套接字绑定到固定的本地端口——客户端需要通过该端口定位服务器而UDP客户端通常无需绑定系统自动分配临时端口。struct sockaddr_in addr; addr.sin_family AF_INET; addr.sin_port htons(12345); addr.sin_addr.s_addr htonl(INADDR_ANY); bind(sockfd, (struct sockaddr *)addr, sizeof(addr));3. sendto() - 发送数据UDP无连接特性决定了其发送数据时需明确指定目标地址——sendto函数正是为此设计它将数据报发送到指定的服务器端地址无需提前建立连接区别于TCP的send。ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);重要说明sendto返回成功仅表示数据已交给内核发送缓冲区不保证对方能接收UDP无确认机制这与TCP的send有本质区别。4. recvfrom() - 接收数据UDP服务器端通过recvfrom接收客户端发送的数据报同时获取发送方客户端的地址信息以便后续回复。ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);阻塞特性默认情况下若套接字无数据可接收recvfrom会一直阻塞直到有数据报到达或被信号中断。5. close() - 关闭套接字close(sockfd);四、完整代码示例UDP服务器端代码#include stdio.h #include stdlib.h #include string.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include unistd.h #define SERVER_PORT 8888 #define BUFFER_SIZE 1024 int main() { int server_fd; struct sockaddr_in server_addr, client_addr; socklen_t client_addr_len sizeof(client_addr); char buffer[BUFFER_SIZE]; // 1. 创建UDP套接字 if ((server_fd socket(AF_INET, SOCK_DGRAM, 0)) 0) { perror(socket creation failed); exit(EXIT_FAILURE); } // 2. 绑定地址 memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_addr.s_addr htonl(INADDR_ANY); // 监听所有网卡 server_addr.sin_port htons(SERVER_PORT); if (bind(server_fd, (struct sockaddr *)server_addr, sizeof(server_addr)) 0) { perror(bind failed); close(server_fd); exit(EXIT_FAILURE); } printf(UDP Server listening on port %d...\n, SERVER_PORT); // 3. 循环收发数据 while (1) { memset(buffer, 0, BUFFER_SIZE); // 接收客户端数据 ssize_t recv_len recvfrom(server_fd, buffer, BUFFER_SIZE - 1, 0, (struct sockaddr *)client_addr, client_addr_len); if (recv_len 0) { perror(recvfrom failed); continue; } buffer[recv_len] \0; printf(Received from %s:%d: %s\n, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer); // 回显数据到客户端 sendto(server_fd, buffer, strlen(buffer), 0, (struct sockaddr *)client_addr, client_addr_len); } close(server_fd); return 0; }UDP客户端代码#include stdio.h #include stdlib.h #include string.h #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include unistd.h #define SERVER_PORT 8888 #define BUFFER_SIZE 1024 int main() { int client_fd; struct sockaddr_in server_addr; char buffer[BUFFER_SIZE]; // 1. 创建UDP套接字 if ((client_fd socket(AF_INET, SOCK_DGRAM, 0)) 0) { perror(socket creation failed); exit(EXIT_FAILURE); } // 2. 配置服务器地址 memset(server_addr, 0, sizeof(server_addr)); server_addr.sin_family AF_INET; server_addr.sin_port htons(SERVER_PORT); inet_pton(AF_INET, 127.0.0.1, server_addr.sin_addr); // 3. 发送数据 const char *message Hello, UDP Server!; sendto(client_fd, message, strlen(message), 0, (struct sockaddr *)server_addr, sizeof(server_addr)); printf(Sent: %s\n, message); // 4. 接收回显数据 socklen_t addr_len sizeof(server_addr); ssize_t recv_len recvfrom(client_fd, buffer, BUFFER_SIZE - 1, 0, (struct sockaddr *)server_addr, addr_len); if (recv_len 0) { buffer[recv_len] \0; printf(Received: %s\n, buffer); } close(client_fd); return 0; }五、UDP与TCP编程的关键差异维度UDPTCP连接方式无连接直接发送数据报面向连接需三次握手建立连接可靠性不可靠不保证数据到达可靠有确认重传机制数据边界保留消息边界流式协议无消息边界需自行处理粘包服务端流程socket→bind→recvfrom/sendtosocket→bind→listen→accept→recv/send客户端流程socket→sendto/recvfromsocket→connect→send/recv适用场景实时音视频、在线游戏、DNS查询文件传输、网页浏览、邮件服务六、错误处理所有系统调用都可能出错合适的错误处理能提高程序的健壮性。使用errno来检查错误代码并利用perror()或strerror()来输出或处理错误信息。常见错误处理示例if (sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)dest_addr, sizeof(dest_addr)) 0) { perror(sendto failed); // 根据errno进行相应处理 }七、UDP编程的注意事项数据报大小限制UDP数据报最大64KB包括头部建议发送数据控制在1472字节以内以太网MTU 1500 - IP头部20 - UDP头部8以避免分片。UDP套接字没有粘包问题但是不能替代TCP套接字因为UDP协议有一个缺陷如果数据发送的途中丢失则数据就丢失了而TCP则不会有这种缺陷。空数据的处理UDP协议是数据报协议传入的数据可为空在传输过程中UDP会对数据进行内部的拼接和处理。断开链接的影响UDP协议是通过解析对方数据中的IP和端口来返回数据的所以一方发生问题并不会影响到另一方。八、进阶应用场景基于UDP可以构建多种实际应用例如回显服务器接收客户端消息并原样返回是UDP编程的“Hello World”英译汉字典服务客户端发送英文单词服务器返回中文释义多线程聊天室使用多线程处理多个客户端实现实时群聊功能这些应用展示了UDP在实际开发中的灵活性和实用性掌握基础后可以进一步探索更复杂的网络应用开发。处理大量并发客户端时可能需要使用多线程pthread库或多进程fork系统调用来实现。
http://www.zskr.cn/news/1377662.html

相关文章:

  • 2026湘潭市黄金回收白银回收铂金回收店铺哪家好 实力靠谱门店排行榜推荐及联系方式 - 亦辰小黄鸭
  • Amlogic S9xxx 电视盒子Armbian改造:从闲置硬件到全功能服务器的5步转型方案
  • 免费论文降AI工具怎么挑?2026实用攻略帮你少走弯路 - 晨晨_分享AI
  • 量子循环神经网络在混沌时序预测中的参数效率与架构对比
  • UE5与Visual Studio 2022编译器兼容性深度解析
  • D3KeyHelper终极指南:5分钟掌握暗黑3智能按键自动化
  • 用OpenCV给图片‘打光’和‘降噪’:cv2.add掩膜(mask)参数的两种高级玩法
  • 告别‘睁眼瞎’:用IA-YOLO的DIP模块,让你的YOLOv3在雾天和暗光下也能‘火眼金睛’
  • 2025百度网盘提速终极方案:pan-baidu-download全功能使用指南
  • 对比直接使用官方API,Taotoken在计费透明性上的实际感受
  • Wand-Enhancer终极指南:三步免费解锁WeMod专业版所有功能
  • Topit终极指南:为什么这款免费开源工具是Mac窗口置顶的最佳选择
  • 5分钟掌握Equalizer APO:打造Windows系统级专业音频调校的终极方案
  • 让老Mac重获新生的技术伙伴:OpenCore Legacy Patcher四阶段升级指南
  • RNN/LSTM/GRU 面试高频题|梯度消失、时序优势
  • 2026忻州市黄金回收白银回收铂金回收店铺哪家好 实力靠谱门店排行榜推荐及联系方式 - 亦辰小黄鸭
  • Obsidian PDF++:重新定义PDF阅读与知识管理的革命性工具
  • 2026国安部重磅披露:境外间谍如何利用民用路由器构建窃密跳板?全链路技术解析与防御指南
  • CVE-2026-35397深度解析:Jupyter Server路径遍历漏洞,CVSS 8.8高危威胁数据科学全生态
  • 18分钟攻陷GitHub!Nx Console投毒事件深度复盘:3800个核心仓库泄露的供应链安全警示
  • Windows记事本安全机制与命令注入原理辨析
  • Unity游戏背包交互实战:用自定义Button组件实现道具的单击、双击与长按拖拽
  • Beyond Compare 5密钥生成终极指南:从逆向工程到实战激活的完整解决方案
  • 3步完成Switch注入:TegraRcmGUI图形化工具完全指南
  • frida-ios-dump完全配置指南:iOS越狱环境下的动态分析环境构建
  • 预测赋能推断:为高成本实验设计提供统计保证的算法选择框架
  • 如何在5分钟内掌握UAssetGUI:Unreal引擎资产编辑终极指南
  • 因果推断统一框架:从Riesz表示器到ATE估计方法融合
  • 黑龙江省哈尔滨寄快递省钱新思路!小众靠谱线上渠道,全国低价跨省寄件少花冤枉钱 - 时讯资讯
  • TVA 登顶工业视觉的 “iPhone 时刻”(10)