重温WIN32 API ------ 一个简单的UDP服务器类

本文介绍了如何使用C++封装一个简单的UDP服务器类,通过专用线程处理接收数据,接收到数据时调用用户指定的回调函数。为了避免复杂的IO处理,没有采用平台相关的IO模型,而是采用线程和回调函数的订阅模式。同时,文章讨论了多线程同步问题,如主线程通过关闭套接字通知侦听线程退出,以及避免在非UI线程中直接更新UI的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一个项目需要使用简单的UDP进行通信,为方便调用,使用C++类封装了一个简单的UDP服务器类。

1 基本思路

网络通信程序设计中最难的部分就是IO的处理,不同操作系统平台提供不同的IO处理机制,Windows平台有select模型、完成端口等,Linux平台则是poll和epoll。由于本项目要求简单,通信量也不大,所以没有采用这些与平台相关的IO模型,而是采用简单的专用线程来负责侦听。当收到数据包时,自动调用用户指定的回调函数,算是设计模式中”订阅模式“的简单实现,也是来自于模仿C#中的event机制。

 

多线程程序必须要考虑同步的问题。主线程通过线程安全地设置一个变量来通知UDP侦听线程退出,为防止侦听线程中的recvfrom()一直阻塞而无法退出线程,主线程采用closesocket()来强制侦听线程的recvfrom()返回。(其他让recvfrom退出的方法包括发送专用udp数据包)

 

另外类使用者需要注意的是,回调函数是在侦听线程中执行,所以要避免非UI线程直接更新UI的问题。回调函数如果涉及到窗口UI操作,需要处理数据后通过SendMessage()的方式通知UI线程,然后由UI线程来实际执行UI更新操作。

2 代码实现

就一个UDPServer类,头文件UDPServer.h,实现文件UDPServer.cpp。

 

#pragma once

#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <iphlpapi.h>

#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "WS2_32")

#include <vector>
using namespace std;

typedef void(*UDPRecvFun)(void* sender, BYTE*, int);   // 收到UDP数据包后的回调函数原型

/*
                            UDP服务器类
功能描述:
建立UDP侦听,建立一个专用线程负责接收UDP数据包。该类采用类似于C#的事件驱动设计模式。

使用样例:
	void AfterRecv(void* sender, BYTE* data, int len)  // 回调函数实现
	{
	   ......
	}

	UDPServer pServer = new UDPServer("127.0.0.1", 8888);
	pServer.AddCallback(AfterRecv);    // 增加一个回调, 收到UDP包后会自动调用此函数

	pServer->StartUDPServer(); // 开始侦听

	pServer->StopUDPServer(); // 可选,因为析构函数会自动调用此方法

	delete pServer;

*/
class
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值