最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
C++怎样实现基于UDP协议的简易客户端服务端双向通信
时间:2026-06-19 08:28:53 编辑:袖梨 来源:一聚教程网
UDP客户端需绑定本地端口(可设0自动分配)并用sendto()向服务端准确IP和端口发送数据,否则数据被静默丢弃;服务端用recvfrom()接收并原样地址回包,无需connect或维护连接状态。
UDP 客户端如何正确绑定并发送数据到服务端
UDP 是无连接协议,客户端不需要显式 connect(),但必须确保目标地址和端口准确;否则发出去的数据包会被内核静默丢弃,且不会报错。常见错误是误用 INADDR_ANY 或本地未绑定端口,导致服务端回包时无法送达(因为内核找不到对应 socket)。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 客户端调用
bind()绑定一个本地端口(哪怕用0让系统自动分配),否则recvfrom()会失败或收不到回包 - 发送前务必用
inet_addr()或inet_pton()检查 IP 字符串合法性,非法地址会导致sendto()返回 -1 且errno为EINVAL - 目标端口必须和服务端监听端口一致;若服务端监听
8080,客户端却发到8081,数据就彻底丢失 - 用
sendto()时,addrlen参数必须是sizeof(sockaddr_in),传小了会导致地址截断,服务端看到的是乱码 IP
UDP 服务端如何安全处理并发收发而不阻塞
单线程 UDP 服务端通常用 recvfrom() 阻塞等待,但这不等于“不能双向通信”——关键在于:每个收到的包都携带源地址信息,服务端可直接用该地址+端口调用 sendto() 回复,无需维护连接状态。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不要在循环里重复
bind();绑定一次即可,重复调用会返回errno = EADDRINUSE - 每次
recvfrom()后,把拿到的sockaddr_in结构体原样传给sendto(),不要重新构造或修改sin_port字段(注意网络字节序已由recvfrom()自动填充) - 若需支持多客户端同时通信,不必开多线程;只要每次回复都用收到的源地址,天然支持“伪并发”
- 避免在
sendto()前对同一sockaddr_in调用htonl()或htons()—— 这些字段已是网络序,二次转换会导致端口变成 0
如何避免 recvfrom() 收不到回包或触发 EAGAIN
recvfrom() 默认阻塞,但若设了 SOCK_NONBLOCK 或 O_NONBLOCK,没数据时会立即返回 -1 并置 errno = EAGAIN 或 EWOULDBLOCK。这不是错误,而是预期行为;盲目重试或忽略它,会导致 CPU 空转或逻辑跳过有效数据。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 检查
recvfrom()返回值:等于 -1 且errno == EAGAIN时,应继续下一轮循环,而非报错退出 - 缓冲区大小至少设为
65536(即 UDP 最大理论包长),小于65507可能导致大数据包被截断,且不提示 - 收到数据后,立刻用
ntohl()/ntohs()解析源 IP 和端口——别依赖打印调试,因为printf("%d", sin_port)会显示错误的主机序数值 - Windows 下需调用
WSAStartup()初始化,否则所有 socket 函数均失败,错误码为WSANOTINITIALISED
跨平台编译时 sockaddr_in 和头文件的典型坑
Linux 和 Windows 对 sockaddr_in 的定义基本一致,但头文件依赖和初始化方式差异明显。最常踩的坑是漏包含、顺序错、或忘记清理资源。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- Linux 必须包含:
<sys/socket.h>、<netinet/in.h>、<arpa/inet.h>;Windows 必须包含:<winsock2.h>,且#include <ws2tcpip.h>在其后 - Windows 下必须在程序开头调用
WSAStartup(MAKEWORD(2,2), &wsaData),结尾调用WSACleanup();漏掉任一都会导致后续 socket 创建失败 -
memset(&addr, 0, sizeof(addr))必须在声明sockaddr_in addr后立即执行,否则sin_zero字段可能含垃圾值,影响地址比较或sendto()行为 - 关闭 socket 时,Linux 用
close(),Windows 用closesocket();混用会导致句柄泄漏或崩溃
相关文章
- 《明日方舟终末地》陈千语怎么样-陈千语值得培养吗 07-04
- 《明日方舟终末地》余烬怎样配队-余烬阵容搭配推荐 07-04
- 《明日方舟终末地》骏卫怎么样-骏卫值得培养吗 07-04
- 《明日方舟终末地》莱万汀怎样配队-莱万汀强力配队推荐 07-04
- 《明日方舟终末地》原木怎样获得-原木获得方法 07-04
- 《长生天机降世》太虚境十天智遗迹幻境通关攻略-详细打法解析 07-04