C++中实现UDP通信需使用套接字API,首先创建套接字,客户端发送数据到服务器并可接收响应,服务器绑定端口监听并回复客户端,核心函数为sendto和recvfrom,需注意跨平台兼容性及资源释放。

在C++中实现UDP通信主要依赖操作系统提供的套接字(Socket)API。UDP是一种无连接的传输协议,适合对实时性要求高、能容忍少量数据丢失的场景,比如音视频传输或游戏通信。下面介绍如何在Linux和Windows平台下使用C++实现基本的UDP通信。
创建UDP客户端
UDP客户端的主要任务是向指定的服务器发送数据,并可选择接收响应。
步骤说明:
- 初始化套接字
- 设置服务器地址信息
- 发送数据到服务器
- 可选:接收服务器返回的数据
- 关闭套接字
示例代码(跨平台兼容,以Linux为主,Windows需初始化WSA):
立即学习“C++免费学习笔记(深入)”;
#include <iostream>
#include <cstring>
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
<p>int main() {</p><h1>ifdef _WIN32</h1><p>WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);</p><h1>endif</h1><p>int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
std::cerr << "Socket creation failed\n";
return -1;
}</p><p>struct sockaddr_in serverAddr;
std::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 目标IP</p><p>const char<em> msg = "Hello UDP Server";
sendto(sock, msg, strlen(msg), 0,
(struct sockaddr</em>)&serverAddr, sizeof(serverAddr));</p><p>// 接收回传消息
char buffer[1024];
socklen_t len = sizeof(serverAddr);
int n = recvfrom(sock, buffer, sizeof(buffer)-1, 0,
(struct sockaddr*)&serverAddr, &len);
if (n > 0) {
buffer[n] = '\0';
std::cout << "Received: " << buffer << std::endl;
}</p><h1>ifdef _WIN32</h1><p>closesocket(sock);
WSACleanup();</p><h1>else</h1><p>close(sock);</p><h1>endif</h1><p>return 0;
}</p>创建UDP服务器
UDP服务器监听指定端口,接收来自客户端的数据并可回传响应。
关键点:
- 绑定本地IP和端口
- 持续监听接收数据
- 可获取客户端地址用于回复
示例代码:
#include <iostream>
#include <cstring>
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#endif
<p>int main() {</p><h1>ifdef _WIN32</h1><p>WSADATA wsa;
WSAStartup(MAKEWORD(2,2), &wsa);</p><h1>endif</h1><p>int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
std::cerr << "Socket creation failed\n";
return -1;
}</p><p>struct sockaddr_in serverAddr;
std::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
serverAddr.sin_port = htons(8888);</p><p>if (bind(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
std::cerr << "Bind failed\n";</p><h1>ifdef _WIN32</h1><pre class='brush:php;toolbar:false;'>closesocket(sock);else
close(sock);
endif
return -1;
}
std::cout << "UDP Server running on port 8888...\n";
char buffer[1024]; struct sockaddr_in clientAddr; socklen_t clientLen = sizeof(clientAddr);
while (true) { int n = recvfrom(sock, buffer, sizeof(buffer)-1, 0, (struct sockaddr*)&clientAddr, &clientLen); if (n > 0) { buffer[n] = '\0'; std::cout << "Client says: " << buffer << std::endl;
// 回复客户端
const char* reply = "ACK";
sendto(sock, reply, strlen(reply), 0,
(struct sockaddr*)&clientAddr, clientLen);
}}
ifdef _WIN32
closesocket(sock); WSACleanup();
else
close(sock);
endif
return 0; }
编译与运行说明
Linux:
- 保存为 .cpp 文件,使用 g++ 编译
- 命令:g++ udp_server.cpp -o server && ./server
Windows:
- 使用 Visual Studio 或 MinGW 编译
- 确保链接 ws2_32.lib(Visual Studio 会自动处理#pragma)
注意事项
- UDP不保证数据到达,也不保证顺序,应用层需自行处理
- 每次 recvfrom 可能收到一个完整的报文(UDP是面向报文的)
- sendto 和 recvfrom 是UDP通信的核心函数
- 跨平台时注意头文件和关闭套接字的差异
基本上就这些。只要理解了套接字的基本流程,UDP通信实现起来并不复杂,但要注意错误处理和资源释放。











