⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udpserver.cpp

📁 UDP的服务器与客户端基类
💻 CPP
字号:


#include "UdpServer.h"

CUdpServer::CUdpServer(short pt) : port(pt), over(false)
{
	listen_thread = NULL;
}

CUdpServer::~CUdpServer(void)
{
	this->over = true;
	if (listen_thread)
	{
		WaitForSingleObject(listen_thread, INFINITE);
		CloseHandle(listen_thread);
		listen_thread = NULL;
	}
	closesocket(sock);
	WSACleanup();
}

int CUdpServer::NonBlockStart(void)
{
	int ret = 0;
	
	ret = Init();
	if (ret < 0)
	{
		return ret;
	}

	DWORD self;
	listen_thread = CreateThread(NULL, 0, ListenThread, \
		reinterpret_cast<LPVOID>(this), 0, &self);
	if (!listen_thread)
	{
		ret = -1;
	}

	return ret;
}


int CUdpServer::BlockStart(void)
{
	int ret = 0;

	ret = Init();
	if (ret < 0)
	{
		return ret;
	}

	char   RecvBuf[MAX_BUF];
	fd_set read_set;
	struct timeval tv;
	memset(&tv, 0, sizeof(tv));

	tv.tv_sec  = BLOCK_TIME;
	tv.tv_usec = 0;

	while (!over)
	{
		struct sockaddr_in peer;
		int len = sizeof(peer);

		FD_ZERO(&read_set);
		FD_SET(sock, &read_set);

		ret = select(0, &read_set, NULL, NULL, &tv);
		if (ret == SOCKET_ERROR)
		{
			continue;
		}
		if (ret == 0)
		{
			continue;
		}

		memset(RecvBuf, 0, sizeof(RecvBuf));
		ret = recvfrom(sock, RecvBuf, MAX_BUF, 0, (sockaddr *)(&peer), &len);
		if (ret == SOCKET_ERROR)
		{
			continue;
		}

		char *pbuf = (char *)malloc(MAX_BUF);
		memmove(pbuf, RecvBuf, MAX_BUF);

		THREAD_PACK *pTem = (THREAD_PACK *)malloc(sizeof(THREAD_PACK));
		pTem->obj = this;
		pTem->buf = pbuf;
		memmove(&(pTem->addr), &peer, sizeof(peer));

		HANDLE hdl;
		DWORD  self;
		hdl = CreateThread(NULL, 0, WorkerThread, \
			reinterpret_cast<LPVOID>(pTem), 0, &self);
	}

	return ret;
}

int CUdpServer::Stop(void)
{
	this->over = true;
	if (listen_thread)
	{
		WaitForSingleObject(listen_thread, INFINITE);
		CloseHandle(listen_thread);
		listen_thread = NULL;
	}
	closesocket(sock);
	WSACleanup();
	this->over = false;

	return 0;
}

int CUdpServer::Restart(void)
{
	Stop();
	return this->NonBlockStart();
}

void CUdpServer::SetPort(short pt)
{
	this->port = pt;
	return ;
}

__int32_t CUdpServer::WriteTo(void *buf, __u_int len, struct sockaddr_in &dest)
{
	__int32_t ret = 0;
	int length = sizeof(dest);

	ret = sendto(sock, (char *)(buf), len, 0, (struct sockaddr *)(&dest), length);
	if (ret == SOCKET_ERROR)
	{
		return -1;
	}

	return ret;
}


int CUdpServer::Init(void)
{
	int ret = 0;
	
	WinVersion = MAKEWORD(2, 2);
	if (WSAStartup(WinVersion, &wsa) < 0)
	{
		return -1;
	}

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == INVALID_SOCKET)
	{
		return -1;
	}
	
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));

	addr.sin_family = AF_INET;
	addr.sin_port   = htons(port);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

	ret = bind(sock, (struct sockaddr *)(&addr), sizeof(addr));
	if (ret == SOCKET_ERROR)
	{
		return -1;
	}

	return ret;
}

DWORD CUdpServer::WorkerThread(LPVOID arg)
{
	THREAD_PACK *pArg = reinterpret_cast<THREAD_PACK *>(arg);
	CUdpServer  *pServer = reinterpret_cast<CUdpServer *>(pArg->obj);

	char recvbuf[MAX_BUF];
	memset(recvbuf, 0, MAX_BUF);
	memmove(recvbuf, pArg->buf, MAX_BUF);

	struct sockaddr_in peer = pArg->addr;

	pServer->Engine(recvbuf, MAX_BUF, peer);

	free(pArg->buf);
	free(pArg);

	return 0;
}

DWORD CUdpServer::ListenThread(LPVOID arg)
{
	CUdpServer *pServer = reinterpret_cast<CUdpServer *>(arg);

	int ret = 0;
	char   RecvBuf[MAX_BUF];
	fd_set read_set;
	struct timeval tv;
	memset(&tv, 0, sizeof(tv));

	tv.tv_sec = BLOCK_TIME;
	tv.tv_usec = 0;

	while (!pServer->over)
	{
		struct sockaddr_in peer;
		int len = sizeof(peer);

		FD_ZERO(&read_set);
		FD_SET(pServer->sock, &read_set);

		ret = select(0, &read_set, NULL, NULL, &tv);

		if (ret == SOCKET_ERROR)
		{
			continue;
		}
		if (ret == 0)
		{
			continue;
		}
		
		memset(RecvBuf, 0, sizeof(RecvBuf));
		ret = recvfrom(pServer->sock, RecvBuf, MAX_BUF, 0, (sockaddr *)(&peer), &len);
		if (ret == SOCKET_ERROR)
		{
			continue;
		}
		
		char *pbuf = (char *)malloc(MAX_BUF);
		memmove(pbuf, RecvBuf, MAX_BUF);

		THREAD_PACK *pTem = (THREAD_PACK *)malloc(sizeof(THREAD_PACK));
		pTem->obj = arg;
		pTem->buf = pbuf;
		memmove(&(pTem->addr), &peer, sizeof(peer));

		HANDLE hdl;
		DWORD  self;
		hdl = CreateThread(NULL, 0, WorkerThread, \
			reinterpret_cast<LPVOID>(pTem), 0, &self);
	}

	return ret;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -