C++ UDP接続方法(MFC版)

UdpSocete.h

/*__________________________UDP-Client__________________________________*/

class UdpClient
{
    
    
public:
	UdpClient();
	UdpClient(const std::string& IP, int Port);
	~UdpClient();
public:
	bool Connect(bool bMutex = false) override;
	void DisConnect(bool bMutex = false) override;
	bool clearBuf_c();
	bool recvBuf_c(char* pStr, int& len, int waitTimeMS = 0) override;
	bool sendBuf_c(char const *pStr, const int& len) override;
protected:
	bool Connect(std::string IP, int Port);
private:
	SOCKET m_socket;
	SOCKADDR_IN m_addrServer;
};

/*__________________________UDP-Server__________________________________*/

class UdpServer
{
    
    
public:
	UdpServer();
	UdpServer(const std::string& IP, int Port);
	~UdpServer();
public:
	bool Connect(bool bMutex = false) override;
	void DisConnect(bool bMutex = false) override;
	bool clearBuf_c();
	bool recvBuf_c(char* pStr, int& len, int waitTimeMS = 0) override;
	bool sendBuf_c(char const *pStr, const int& len) override;
protected:
	bool Connect(std::string IP, int Port);
private:
	SOCKET m_socket;
	SOCKADDR_IN m_addrServer;
	SOCKADDR_IN m_addrClient;
	std::list<SOCKADDR_IN> m_socketClientList;
};

UdpSocete.cpp


/*__________________________UDP-Client__________________________________*/

UdpClient::UdpClient(void)
{
    
    
	m_socket = SOCKET_ERROR;
	m_typeName = "UDP-服务器";
}

UdpClient::UdpClient(const std::string& IP, int Port)
	: ISocketBaese(IP, Port, SOCKET_TYPE_UDP_CLINET)
{
    
    
	m_socket = SOCKET_ERROR;
	m_typeName = "UDP-服务器";
}

UdpClient::~UdpClient(void)
{
    
    
}

bool UdpClient::Connect(bool bMutex)
{
    
    
	if (bMutex)
	{
    
    
		QMutexLocker locker(&m_Mutex);
		return Connect(m_IP, m_Port);
	}
	return Connect(m_IP, m_Port);
}

bool UdpClient::Connect(std::string IP, int Port)
{
    
    
	DisConnect();
	char strIp[1024];
	memset(strIp, '\0', 1024);
	memcpy(strIp, IP.c_str(), IP.length());

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(1, 1);
	err = WSAStartup(wVersionRequested, &wsaData);//该函数的功能是加载一个Winsocket库版本
	if (err != 0)
		return false;

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
    
    
		DisConnect();
		return false;
	}
	m_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (m_socket == INVALID_SOCKET)
	{
    
    
		DisConnect();
		return false;
	}
	u_long u1 = 1;
	if (SOCKET_ERROR == ioctlsocket(m_socket, FIONBIO, &u1))
	{
    
    
		DisConnect();
		return false;
	}

	memset((char*)&m_addrServer, 0, sizeof(m_addrServer));
	m_addrServer.sin_addr.S_un.S_addr = inet_addr(strIp);
	m_addrServer.sin_family = AF_INET;
	m_addrServer.sin_port = htons(Port);

	//memset((char*)&m_addrClient, 0, sizeof(m_addrClient));
	//m_addrClient.sin_addr.S_un.S_addr = inet_addr(strIp);
	//m_addrClient.sin_family = AF_INET;
	//m_addrClient.sin_port = htons(Port);
	//int rtn = bind(m_socket, (sockaddr*)&m_addrClient, sizeof(m_addrClient));
	//if (rtn != 0)
	//{
    
    
	//	return false;
	//}
	m_bConnectOK = true;
	return true;
}

void UdpClient::DisConnect(bool bMutex)
{
    
    
	if (m_socket != SOCKET_ERROR)
	{
    
    
		closesocket(m_socket);
		//WSACleanup();
	}
	m_bConnectOK = false;
	m_socket = SOCKET_ERROR;
}

bool UdpClient::clearBuf_c()
{
    
    
	bool rtn = 0;
	SOCKADDR_IN temp_in;
	int formLen = sizeof(SOCKADDR_IN);
	do
	{
    
    
		if (recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen) <= 0)
			break;
	} while (1);
	return true;
}

bool UdpClient::recvBuf_c(char* pStr, int& len, int waitTimeMS)
{
    
    
	QMutexLocker locker(&m_Mutex);
	memset(m_recvBuffer, '\0', CHAR_LEN);
	int buflen;
	SOCKADDR_IN temp_in;
	int formLen = sizeof(SOCKADDR_IN);
	DWORD initTime = GetTickCount();
	while (true)
	{
    
    
		buflen = recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen);
		if (buflen > 0)
		{
    
    
			if (m_addrServer.sin_addr.S_un.S_addr != temp_in.sin_addr.S_un.S_addr\
				|| m_addrServer.sin_port != temp_in.sin_port)
				return false;
			memcpy(pStr, m_recvBuffer, buflen);
			len = buflen;
			return true;
		}
		//当接受数据时断开连接会返回0
		else if (buflen == 0)
		{
    
    
			m_bConnectOK = false;
			Connect();
			return false;
		}
		//初始等待连接或是已连接未收到数据返回-1
		else if (buflen < 0)
		{
    
    
			if (!m_bConnectOK)
				Connect();
			if (abs(int(GetTickCount() - initTime)) > waitTimeMS)
				return false;
		}
	}
	return true;
}

bool UdpClient::sendBuf_c(char const *pStr, const int& len)
{
    
    
	QMutexLocker locker(&m_Mutex);
	int rtn = sendto(m_socket, pStr, len, 0, (sockaddr*)&m_addrServer, sizeof(SOCKADDR_IN));
	if (rtn < 0)
	{
    
    
		return false;
	}
	return true;
}

/*__________________________UDP-Server__________________________________*/

UdpServer::UdpServer(void)
{
    
    
	m_socket = SOCKET_ERROR;
	m_typeName = "UDP-服务器";
}

UdpServer::UdpServer(const std::string& IP, int Port)
	: ISocketBaese(IP, Port, SOCKET_TYPE_UDP_SERVER)
{
    
    
	m_socket = SOCKET_ERROR;
	m_typeName = "UDP-服务器";
}

UdpServer::~UdpServer(void)
{
    
    
}

bool UdpServer::Connect(bool bMutex)
{
    
    
	if (bMutex)
	{
    
    
		QMutexLocker locker(&m_Mutex);
		return Connect(m_IP, m_Port);
	}
	return Connect(m_IP, m_Port);
}

bool UdpServer::Connect(std::string IP, int Port)
{
    
    
	DisConnect();
	char strIp[1024];
	memset(strIp, '\0', 1024);
	memcpy(strIp, IP.c_str(), IP.length());

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(1, 1);
	err = WSAStartup(wVersionRequested, &wsaData);//该函数的功能是加载一个Winsocket库版本
	if (err != 0)
		return false;

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
    
    
		DisConnect();
		return false;
	}
	m_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (m_socket == INVALID_SOCKET)
	{
    
    
		DisConnect();
		return false;
	}
	u_long u1 = 1;
	if (SOCKET_ERROR == ioctlsocket(m_socket, FIONBIO, &u1))
	{
    
    
		DisConnect();
		return false;
	}
	//memset((char*)&m_addrOtherSide, 0, sizeof(m_addrOtherSide));
	//m_addrOtherSide.sin_addr.S_un.S_addr = inet_addr(strIp);
	//m_addrOtherSide.sin_family = AF_INET;
	//m_addrOtherSide.sin_port = htons(Port);

	memset((char*)&m_addrServer, 0, sizeof(m_addrServer));
	m_addrServer.sin_addr.S_un.S_addr = inet_addr(strIp);
	m_addrServer.sin_family = AF_INET;
	m_addrServer.sin_port = htons(Port);
	int rtn = bind(m_socket, (sockaddr*)&m_addrServer, sizeof(m_addrServer));
	if (rtn != 0)
	{
    
    
		return false;
	}

	//sockaddr addr;
	//sockaddr_in* addr_v4;
	//int addr_len = sizeof(addr);
	//getsockname(m_socket, &addr, &addr_len);
	//addr_v4 = (sockaddr_in*)(&addr);


	m_bConnectOK = true;
	return true;
}

void UdpServer::DisConnect(bool bMutex)
{
    
    
	if (m_socket != SOCKET_ERROR)
	{
    
    
		closesocket(m_socket);
		//WSACleanup();
	}
	m_socketClientList.clear();
	m_bConnectOK = false;
	m_socket = SOCKET_ERROR;
}

bool UdpServer::clearBuf_c()
{
    
    
	bool rtn = 0;
	SOCKADDR_IN temp_in;
	int formLen = sizeof(SOCKADDR_IN);
	do
	{
    
    
		if (recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen) <= 0)
			break;
	} while (1);
	return true;
}

bool UdpServer::recvBuf_c(char* pStr, int& len, int waitTimeMS)
{
    
    
	QMutexLocker locker(&m_Mutex);
	memset(m_recvBuffer, '\0', CHAR_LEN);
	int buflen;
	SOCKADDR_IN temp_in;
	int formLen = sizeof(SOCKADDR_IN);
	DWORD initTime = GetTickCount();
	while (true)
	{
    
    
		buflen = recvfrom(m_socket, m_recvBuffer, CHAR_LEN, 0, (sockaddr*)&temp_in, &formLen);
		if (buflen > 0)
		{
    
    
			bool addFlag = 0;
			for (auto&it : m_socketClientList)
			{
    
    
				if (it.sin_addr.S_un.S_addr == temp_in.sin_addr.S_un.S_addr\
					&& it.sin_port == temp_in.sin_port)
					addFlag = 1;
			}
			if (addFlag == 0)
				m_socketClientList.push_back(temp_in);
			m_addrClient = temp_in;
			memcpy(pStr, m_recvBuffer, buflen);
			len = buflen;
			return true;
		}
		//当接受数据时断开连接会返回0
		else if (buflen == 0)
		{
    
    
			m_bConnectOK = false;
			Connect();
			return false;
		}
		//初始等待连接或是已连接未收到数据返回-1
		else if (buflen < 0)
		{
    
    
			if (!m_bConnectOK)
				Connect();
			if (abs(int(GetTickCount() - initTime)) > waitTimeMS)
				return false;
		}
	}
	return true;
}

bool UdpServer::sendBuf_c(char const *pStr, const int& len)
{
    
    
	QMutexLocker locker(&m_Mutex);
	int rtn = sendto(m_socket, pStr, len, 0, (sockaddr*)&m_addrClient, sizeof(SOCKADDR_IN));
	if (rtn < 0)
	{
    
    
		return false;
	}
	return true;
}


おすすめ

転載: blog.csdn.net/Liang_ming_/article/details/131667308