这个类,只求简单,不求严谨;
#ifndef win_udp_Socke_h__
#define win_udp_Socke_h__
#include <thread>
#include <iostream>
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib")
//UDPServer
class CUdpServerRecv
{
public:
virtual void incoming_recv(uint8_t * pbuf, int nLen) = 0;
};
class CWinUdpServer_test
{
public:
CWinUdpServer_test( uint16_t nServerPort, CUdpServerRecv * pUdpServerRecv )
{
m_pUdpServerRecv = pUdpServerRecv;
init(nServerPort);
}
~CWinUdpServer_test()
{
m_pUdpServerRecv = 0;
Sleep(100);
if (sockServer!= INVALID_SOCKET)
{
//关闭套接字
closesocket(sockServer);
}
Sleep(100);
}
static int thread_Udp_recv(CWinUdpServer_test * pParam)
{
int len = sizeof(SOCKADDR);
const int nRecvLen = 1500;
uint8_t recvBuf[nRecvLen] = {0};
while (pParam->m_pUdpServerRecv)
{
int nRecv = recvfrom(pParam->sockServer, (char*)recvBuf, nRecvLen, 0, (SOCKADDR*)&(pParam->addrClient), &len);
if (pParam->m_pUdpServerRecv)
{
pParam->m_pUdpServerRecv->incoming_recv(recvBuf, nRecv);
}
}
return 0;
}
private:
CUdpServerRecv * m_pUdpServerRecv;
private:
SOCKET sockServer;
SOCKADDR_IN addrClient;//用于接收发送端的地址信息
private:
int init(int SERVERPORT)
{
/* The WinSock DLL is acceptable. Proceed. */
//创建套接字
sockServer = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == sockServer)
{
printf("socket() called failed! The error code is: %d\n", WSAGetLastError());
return -1;
}
else
{
printf("socket() called succesful!\n");
}
//服务器端
SOCKADDR_IN addrServer;
addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(SERVERPORT);
//绑定套接字
int err = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
if (SOCKET_ERROR == err)
{
printf("bind() called failed! The error code is: %d\n", WSAGetLastError());
return -1;
}
printf("bind() called successful!\n");
std::thread threadUdpRecv(thread_Udp_recv, this);
threadUdpRecv.detach();
//等待并接收数据
// int len = sizeof(SOCKADDR);
// char recvBuf[100];
// int nRecv = recvfrom(sockServer, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len);
//
// return nRec
return 1;
}
public:
};
class CWinUdpClient_test
{
public:
CWinUdpClient_test( char * pstrIp, uint16_t nPort)
{
//创建套接字
sockClient = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == sockClient)
{
printf("failed! : %d\n", WSAGetLastError());
return;
}
else
{
printf("succesful!\n");
}
addrServer.sin_addr.S_un.S_addr = inet_addr(pstrIp);
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(nPort);
}
~CWinUdpClient_test()
{
//关闭套接字
closesocket(sockClient);
}
private:
SOCKET sockClient;
SOCKADDR_IN addrServer;
public:
int send_to( uint8_t * pbuf , int nLen)
{
//发送数据
int err = sendto(sockClient, (char*)pbuf, nLen, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
if (SOCKET_ERROR == err)
{
printf("%s\n", WSAGetLastError());
return -1;
}
return err;
}
};
class CWinUdpManager_test : public CUdpServerRecv
{
public:
CWinUdpManager_test(uint16_t nServerPort, CUdpServerRecv * pUdpServerRecv, char * strClientIp, uint16_t nClientPort)
{
m_pCUdpServerRecv = pUdpServerRecv; //这里的定义,主要是将数据给外部指定的函数;
init();
m_pUdpServer = NULL;
m_pUdpServer = new CWinUdpServer_test(nServerPort, this);
m_pUdpClient = NULL;
//m_pUdpClient = new CWinUdpClient_test(strClientIp, nClientPort);
}
~CWinUdpManager_test()
{
SAFE_DELETE(m_pUdpServer);
SAFE_DELETE(m_pUdpClient);
//终止套接字库的使用
WSACleanup();
}
public:
virtual void incoming_recv(uint8_t * pbuf, int nLen) override
{
//throw std::logic_error("The method or operation is not implemented.");
m_pCUdpServerRecv->incoming_recv(pbuf, nLen);
}
private:
int init()
{
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return -1;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup();
return -1;
}
}
CUdpServerRecv * m_pCUdpServerRecv;
private:
//加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
private:
public:
CWinUdpServer_test * m_pUdpServer;
CWinUdpClient_test * m_pUdpClient;
};
#endif // win_udp_Socke_h__
也可以到我都CSDN下载;