博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单的c++ UDP类 + 多线程 win32编程
阅读量:4179 次
发布时间:2019-05-26

本文共 4428 字,大约阅读时间需要 14 分钟。

UdpClient.h

#include "Thread.h"class IUdpRecvCallback{public:    virtual void OnRecv(const char* buf, USHORT len, const char* fromIp, USHORT fromPort) = 0;};class CUdpClient : public IRunnable{public:    CUdpClient(IUdpRecvCallback* callback);    ~CUdpClient();public:    BOOL Start(USHORT localPort);    void Stop();    BOOL SendTo(const char* buf, USHORT len, const char* remoteIp, USHORT remotePort);protected:    virtual void Run()override;private:    SOCKET m_sock;    CThread* m_thread = nullptr;    BOOL m_running = FALSE;    IUdpRecvCallback* m_recvCallback = nullptr;};

UdpClient.cpp

#include "UdpClient.h"#include 
#pragma comment(lib, "ws2_32.lib")CUdpClient::CUdpClient(IUdpRecvCallback* callback){ m_recvCallback = callback;}CUdpClient::~CUdpClient(){ Stop();}BOOL CUdpClient::Start(USHORT localPort){ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { TRACE(_T("WSAStartup error\n")); return FALSE; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { TRACE(_T("WSAStartup version is not right\n")); WSACleanup(); return FALSE; } m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (m_sock == INVALID_SOCKET) { TRACE(_T("socket failed with error: %ld\n"), WSAGetLastError()); WSACleanup(); return FALSE; } SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(localPort); if (-1 == bind(m_sock, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))) { TRACE(_T("bind failed with error: %ld\n"), WSAGetLastError()); WSACleanup(); return FALSE; } int nRecvBuf = 700 * 1024;//设置为700K if (0 != setsockopt(m_sock, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int))) { TRACE(_T("setsockopt buf size failed.\n"), WSAGetLastError()); return FALSE; } if (m_thread == nullptr) { m_thread = new CThread(this); m_running = TRUE; m_thread->Start(); } return TRUE;}void CUdpClient::Stop(){ closesocket(m_sock); m_sock = INVALID_SOCKET; m_running = FALSE; m_thread->WaitFinish(); delete m_thread; WSACleanup();}BOOL CUdpClient::SendTo(const char * buf, USHORT len, const char* remoteIp, USHORT remotePort){ if (INVALID_SOCKET == m_sock) { TRACE(_T("socket is invalid.\n")); return FALSE; } sockaddr_in recvAddr; int iResult; recvAddr.sin_family = AF_INET; recvAddr.sin_port = htons(remotePort); recvAddr.sin_addr.s_addr = inet_addr(remoteIp); iResult = sendto(m_sock,(const char *)buf, len, 0, (SOCKADDR *)& recvAddr, sizeof(recvAddr)); if (iResult == SOCKET_ERROR) { TRACE(_T("sendto failed with error: %d\n"), WSAGetLastError()); return FALSE; } return TRUE;}static char s_recvBuf[1024];void CUdpClient::Run(){ TRACE(_T("Run\n")); while (m_running) { int bufLen = 1024; sockaddr_in senderAddr; int senderAddrSize = sizeof(senderAddr); int result = recvfrom(m_sock, s_recvBuf, bufLen, 0, (SOCKADDR *)& senderAddr, &senderAddrSize); if (result < 0) { TRACE(_T("recvfrom failed with error %d\n"), WSAGetLastError()); continue; } char *fromip = inet_ntoa(senderAddr.sin_addr); if (m_recvCallback != nullptr) { m_recvCallback->OnRecv(s_recvBuf, result, fromip, senderAddr.sin_port); } }}

 

Thread.h

#pragma onceclass IRunnable{public:    virtual void Run() = 0;};class CThread{public:    CThread(IRunnable * run);    ~CThread();public:    void Start();    void WaitFinish();public:    IRunnable* m_run = NULL;    HANDLE m_hThread = NULL;};

/Thread.cpp

CThread::CThread(IRunnable * run){    m_run = run;}CThread::~CThread(){    ::CloseHandle(m_hThread);    m_hThread = NULL;}static DWORD WINAPI ThreadFunc(LPVOID param){    CThread* thread = (CThread*)param;    if (thread->m_run != NULL)    {        thread->m_run->Run();    }    return 0;}void CThread::Start(){    if (m_hThread == NULL)    {        DWORD dwThreadID = 0;        m_hThread = ::CreateThread(NULL, 0, ThreadFunc, this, 0, &dwThreadID);    }}void CThread::WaitFinish(){    if (m_hThread != NULL)        ::WaitForSingleObject(m_hThread, INFINITE);}

转载地址:http://zwmai.baihongyu.com/

你可能感兴趣的文章
HTTP请求工具类
查看>>
Ngnix+tomcat 集群以及session共享
查看>>
Nginx配置多个项目放在不同的tomcat中,共享同一个端口
查看>>
mysql的JDBC连接工具类
查看>>
ORACLE的JDBC连接工具类
查看>>
利用多线程(用到原子类AtomicInteger)往数据库批量插入大量数据
查看>>
多个线程操作数组
查看>>
定长线程池的应用
查看>>
生产者和消费者模式
查看>>
ArrayBlockingQueue的简单使用
查看>>
Git 常用命令总结(一)
查看>>
Git 常用命令总结(二)
查看>>
JAVA 并发——synchronized的分析
查看>>
Echarts——使用 dataset 管理数据
查看>>
DES 加解密工具类
查看>>
JAVA乱码问题——URL中的+,空格,/,?,%,#,&,= 及转义处理
查看>>
Base64编解码工具类
查看>>
使用IntelliJ IDEA2018创建Maven多模块项目
查看>>
SpringBoot多模块项目实践(Multi-Module)
查看>>
第一篇: 服务的注册与发现Eureka(Greenwich版)
查看>>