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

【Windows】【C++】【Udp】 udp通信协议详解和示例

在 Windows 平台上,使用 C++ 实现的 UDP 通信服务器和客户端示例代码稍有不同,因为 Windows 使用 Winsock API 进行网络编程。下面是一个简单的 UDP 服务器和客户端的实现示例,包括详细的代码和说明。

UDP 服务器代码示例(Windows)

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    // 初始化 Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Winsock initialization failed" << std::endl;
        return -1;
    }

    // 创建套接字
    SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd == INVALID_SOCKET) {
        std::cerr << "Socket creation failed" << std::endl;
        WSACleanup();
        return -1;
    }

    // 设置服务器地址结构
    struct sockaddr_in serverAddr, clientAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    memset(&clientAddr, 0, sizeof(clientAddr));

    serverAddr.sin_family = AF_INET; // IPv4
    serverAddr.sin_addr.s_addr = INADDR_ANY; // 任意地址
    serverAddr.sin_port = htons(PORT); // 端口号

    // 绑定套接字到地址
    if (bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Bind failed" << std::endl;
        closesocket(sockfd);
        WSACleanup();
        return -1;
    }

    std::cout << "UDP Server is up and listening on port " << PORT << std::endl;

    while (true) {
        char buffer[BUFFER_SIZE];
        int clientAddrLen = sizeof(clientAddr);
        int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
        if (n == SOCKET_ERROR) {
            std::cerr << "recvfrom failed" << std::endl;
            continue;
        }
        
        buffer[n] = '\0'; // 添加字符串结束符
        std::cout << "Received: " << buffer << std::endl;

        // 发送回应给客户端
        sendto(sockfd, buffer, n, 0, (struct sockaddr*)&clientAddr, clientAddrLen);
        std::cout << "Echoed back to client" << std::endl;
    }

    closesocket(sockfd);
    WSACleanup();
    return 0;
}

UDP 客户端代码示例(Windows)

#include <iostream>

#include <string>

#include <winsock2.h>
#include <ws2tcpip.h>

#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库

#define PORT 8080
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024

int main()
{
// 初始化 Winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		std::cerr << "Winsock initialization failed" << std::endl;
		return -1;
	}

	// 创建套接字
	SOCKET sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (sockfd == INVALID_SOCKET) {
		std::cerr << "Socket creation failed" << std::endl;
		WSACleanup();
		return -1;
	}

	// 设置服务器地址结构
	struct sockaddr_in serverAddr;
	memset(&serverAddr, 0, sizeof(serverAddr));

	serverAddr.sin_family = AF_INET; // IPv4
	serverAddr.sin_port = htons(PORT); // 端口号
	inet_pton(AF_INET, SERVER_IP, &serverAddr.sin_addr); // 服务器 IP

	while (true) {
		std::string message;
		std::cout << "Enter message: ";
		std::getline(std::cin, message);

		// 发送消息到服务器
		sendto(sockfd, message.c_str(), message.size(), 0, (const struct sockaddr*)&serverAddr, sizeof(serverAddr));

		// 接收服务器的回应
		char buffer[BUFFER_SIZE];
		int serverAddrLen = sizeof(serverAddr);
		int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr*)&serverAddr, &serverAddrLen);
		if (n == SOCKET_ERROR) {
			std::cerr << "recvfrom failed" << std::endl;
			continue;
		}

		buffer[n] = '\0'; // 添加字符串结束符
		std::cout << "Server: " << buffer << std::endl;
	}

	closesocket(sockfd);
	WSACleanup();
	return 0;
}

代码详解

  1. 头文件包含:

    • winsock2.h 和 ws2tcpip.h 是 Windows 中网络编程需要的头文件。
    • 使用 #pragma comment(lib, "ws2_32.lib") 语句链接 Winsock 库。
  2. 初始化 Winsock:

    • 在进行任何其他网络操作之前,我们需要调用 WSAStartup() 来初始化 Winsock 库。
  3. 套接字创建:

    • 使用 socket() 函数创建一个 UDP 套接字,返回一个套接字描述符。
  4. 地址结构配置:

    • 服务器地址配置 INADDR_ANY 表示监听来自任意 IP 的数据,端口号固定为 8080。
    • 客户端设定目标服务器的 IP 地址和端口号。
  5. 绑定套接字:

    • 使用 bind() 函数将创建的套接字与指定地址和端口绑定。
  6. 数据接收和发送:

    • 服务器使用 recvfrom() 函数接收数据,并使用 sendto() 函数将数据回传给客户端。
    • 客户端发送数据后,使用 recvfrom() 接收服务器的回应。
  7. 清理资源:

    • 最后使用 closesocket() 关闭套接字,调用 WSACleanup() 清理 Winsock 资源。

编译和运行

要编译这些代码,通常在 Windows 上使用 Visual Studio 或者在命令行中使用以下命令(假设使用 g++ 编译器):

g++ udp_server.cpp -o udp_server -lws2_32
g++ udp_client.cpp -o udp_client -lws2_32
./udp_server
./udp_client

测试

  1. 启动 UDP 服务器,它会开始监听来自客户端的消息。
  2. 之后启动 UDP 客户端,输入消息并按下回车键,消息会发送到服务器,并收到服务器返回的回显信息。

以上是一个简单的 Windows 平台下的 UDP 通信的实现,希望对你有所帮助。如果你有进一步的问题,请随时提问!


http://www.kler.cn/news/294491.html

相关文章:

  • 力扣 797. 所有可能路径【DFS】
  • 尚品汇-商品上下架完善(更新ES)、延迟消息(四十四)
  • CSDN文章无水印转成PDF
  • 【数据结构入门】排序算法之交换排序与归并排序
  • UE5.3_跟一个插件—Socket.IO Client
  • 【爬虫软件】小红薯评论区采集工具
  • 目标检测-RT-DETR
  • 抖音发布Unity小游戏的errorMsg: native build failed
  • 【人工智能学习笔记】1_人工智能基础
  • 【redis】数据量庞大时的应对策略
  • 从源码角度分析 Kotlin by lazy 的实现
  • 固态硬盘装系统有必要分区吗?
  • 前端安全:如何防范跨站脚本攻击(XSS)
  • 【时时三省】c语言例题----华为机试题<等差数列>。
  • 日志系统前置知识
  • 机器人可能会在月球上提供帮助
  • c++的基本数据类型
  • 堆-数组的堆化+优先队列(PriorityQueue)的使用
  • python的logging模块setLevel(LEVELS.get(‘default‘,logging.NOTSET))
  • 如何把自动获取的ip地址固定
  • 每日一题~cf 970 div3 (A思维,B小模拟,C二分,D排列数建图成环,E 26个字母暴力+前缀和,F 逆元,G 数论gcd )
  • 13款常用AI编程工具
  • 稳定的亚马逊自养号测评系统需具备哪些条件
  • Redis:Redis性能变慢的原因
  • JavaScript 知识点总结
  • Linux下安装使用Git及常用操作命令详解
  • AIOT人工智能物联网六大场景
  • Linux下基于TCP协议的简易服务器实现(C语言)
  • OpenCV中的颜色映射函数applyColorMap的使用
  • LCP 485. 最大连续 1 的个数[lleetcode -11]