C++使用UDP

对C++使用UDP做了简单封装,支持zlib压缩后发送数据。

udp.h

#pragma once
#include "SocketInit.h"
#include "TcpEvent.h"

class Udp
{
	Udp();
    ~Udp();
public:
	static Udp& GetInstance();
	void SetBindAddress(const char* ip = "127.0.0.1", int port = 0);
	void SetRemoteAddress(const char* ip, int port);
	bool Init(bool setBroadCast);
	void Close();
	int SendTo(TcpEvent* tcpEvent);
	int RecvFrom(TcpEvent* tcpEvent);
	bool ZipSendTo(TcpEvent* tcpEvent);
	bool ZipRecvFrom(TcpEvent* tcpEvent);



private:
	static Udp m_Instance;
	SOCKET  m_Socket;
	sockaddr_in m_BindAddress;
	sockaddr_in m_RemoteAddress;
	int m_RemoteAddressLen;
};

udp.cpp

#include "Udp.h"
#include "Logger.h"
#include "zip/zlib.h"
#include 
#include 

using namespace std;

Udp Udp::m_Instance;

Udp::Udp()
{
	m_Socket = INVALID_SOCKET;
	memset(&m_BindAddress, 0, sizeof(m_BindAddress));
	memset(&m_RemoteAddress, 0, sizeof(m_BindAddress));
	m_RemoteAddressLen = sizeof(SOCKADDR);
}
Udp::~Udp()
{
	closesocket(m_Socket);
}
Udp& Udp::GetInstance()
{
	return m_Instance;
}
void Udp::SetBindAddress(const char* ip, int port)
{
	m_BindAddress.sin_family = AF_INET;
	m_BindAddress.sin_addr.S_un.S_addr = inet_addr(ip);
	m_BindAddress.sin_port = htons(port);

	WRITE_LOG(LogLevel::Info, "Udp SetBindAddress IP[%s], Port[%d]", ip, port);
}
void Udp::SetRemoteAddress(const char* ip, int port)
{
	m_RemoteAddress.sin_family = AF_INET;
	m_RemoteAddress.sin_addr.S_un.S_addr = inet_addr(ip);
	m_RemoteAddress.sin_port = htons(port);

	m_RemoteAddressLen = sizeof(m_RemoteAddress);
	
	WRITE_LOG(LogLevel::Info, "Udp SetRemoteAddress IP[%s], Port[%d]", ip, port);
}
bool Udp::Init(bool setBroadCast)
{
	m_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (m_Socket == INVALID_SOCKET)
	{
		WRITE_LOG(LogLevel::Error, "Create Udp Socket Failed.");
		Close();
		return false;
	}
	if (setBroadCast)
	{
		BOOL bBroadcast = TRUE;
		if (::setsockopt(m_Socket, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL)) == SOCKET_ERROR)
		{
			WRITE_LOG(LogLevel::Error, "setsockopt SO_BROADCAST Failed.");
			Close();
			return false;
		}
	}
	auto ret = bind(m_Socket, (sockaddr*)&m_BindAddress, sizeof(SOCKADDR));
	if (ret == SOCKET_ERROR)
	{
		WRITE_LOG(LogLevel::Error, "bind Failed. ret[%d]", ret);
		Close();
		return false;
	}
	WRITE_LOG(LogLevel::Info, "Udp Init Successed.");
	return true;
}
void Udp::Close()
{
	closesocket(m_Socket);
	m_Socket = INVALID_SOCKET;
}

int Udp::SendTo(TcpEvent* tcpEvent)
{
	auto sendLen = ::sendto(m_Socket, tcpEvent->ReadPos, tcpEvent->Length, 0, (sockaddr*)&m_RemoteAddress, sizeof(m_RemoteAddress));
	WRITE_LOG(LogLevel::Info, "Udp SendTo:[%s:%u], Len:[%d], Ret:[%d], Buff:[%s]", inet_ntoa(m_RemoteAddress.sin_addr), ntohs(m_RemoteAddress.sin_port), tcpEvent->Length, sendLen, (unsigned char*)tcpEvent->Buff);
	cout << "[";
	for (auto i = 0; i < sendLen; i++)
	{
		printf("%02x", (unsigned char)tcpEvent->ReadPos[i]);
	}
	cout <<"]" << endl;
	return sendLen;
}
int Udp::RecvFrom(TcpEvent* tcpEvent)
{
	int recvLen = recvfrom(m_Socket, tcpEvent->Buff, BuffSize - 1, 0, (SOCKADDR*)&m_RemoteAddress, &m_RemoteAddressLen);
	WRITE_LOG(LogLevel::Info, "Udp RecvFrom:[%s:%u], recvLen:[%d]", inet_ntoa(m_RemoteAddress.sin_addr), ntohs(m_RemoteAddress.sin_port), recvLen);
	tcpEvent->Length = recvLen;
	cout << "[";
	for (auto i = 0; i < recvLen; i++)
	{
		printf("%02x", (unsigned char)tcpEvent->ReadPos[i]);
	}
	cout << "]" << endl;
	return recvLen;
}
bool Udp::ZipSendTo(TcpEvent* tcpEvent)
{
	WRITE_LOG(LogLevel::Info, "Udp ZipSendTo: Len:[%d], Buff:[%s]", tcpEvent->Length, tcpEvent->ReadPos);
	TcpEvent* tcpEvent2 = TcpEvent::Allocate();
	unsigned long destLen = BuffSize;
	auto ret = compress2((unsigned char*)tcpEvent2->Buff, &destLen, (unsigned char*)tcpEvent->Buff, tcpEvent->Length, Z_BEST_SPEED);
	auto result = true;
	if (ret != Z_OK)
	{
		WRITE_LOG(LogLevel::Error, "compress Failed. ret:[%d]", ret);
		result = false;
	}
	else
	{
		tcpEvent2->Length = destLen;
		result = SendTo(tcpEvent2) > 0;
	}
	tcpEvent2->Free();
	return result;
}
bool Udp::ZipRecvFrom(TcpEvent* tcpEvent)
{
	TcpEvent* tcpEvent2 = TcpEvent::Allocate();
	auto result = true;
	int len = RecvFrom(tcpEvent2);
	if (len <= 0)
	{
		tcpEvent2->Free();
		return false;
	}
	unsigned long sourceLen = len;
	unsigned long destLen = BuffSize - 1;
	auto ret = uncompress2((unsigned char*)tcpEvent->Buff, &destLen, (const unsigned char*)tcpEvent2->Buff, &sourceLen);
	if (ret != Z_OK)
	{
		WRITE_LOG(LogLevel::Error, "compress Failed. ret:[%d]", ret);
		result = false;
	}
	else
	{
		tcpEvent->Length += destLen;
		tcpEvent->Buff[tcpEvent->Length] = '\0';
		WRITE_LOG(LogLevel::Info, "Udp ZipRecvFrom: Len:[%d], Buff:[%s]", tcpEvent->Length, tcpEvent->ReadPos);
	}
	tcpEvent2->Free();
	return ret;
}

UdpClient:

#include "Logger.h"
#include "Udp.h"
#include 

using namespace std;

void UdpTest()
{
	Udp::GetInstance().SetBindAddress();
	Udp::GetInstance().SetRemoteAddress("127.0.0.1", 6000);
	Udp::GetInstance().Init(true);

	while (true)
	{
		TcpEvent* tcpEvent = TcpEvent::Allocate();
		cin >> tcpEvent->Buff;
		tcpEvent->Length = strlen(tcpEvent->Buff) + 1;
		Udp::GetInstance().ZipSendTo(tcpEvent);
		tcpEvent->Free();
	}
}


int main(int argc, char* argv[])
{
	Logger::GetInstance().Init(argv[0]);
	Logger::GetInstance().Start();
	UdpTest();

	Logger::GetInstance().Stop();
	Logger::GetInstance().Join();
	return 0;
}

UdpServer:

#include "Logger.h"
#include "Udp.h"


using namespace std;

void UdpTest()
{
	Udp::GetInstance().SetBindAddress("127.0.0.1", 6000);
	if (!Udp::GetInstance().Init(false))
	{
		return;
	}

	while (true)
	{
		TcpEvent* tcpEvent = TcpEvent::Allocate();
		Udp::GetInstance().ZipRecvFrom(tcpEvent);
		tcpEvent->Free();
	}
}


int main(int argc, char* argv[])
{
	Logger::GetInstance().Init(argv[0]);
	Logger::GetInstance().Start();
	UdpTest();

	Logger::GetInstance().Stop();
	Logger::GetInstance().Join();
	return 0;
}

UdpClient输出:

ThreadID[44592] Udp SetBindAddress IP[127.0.0.1], Port[0]
ThreadID[44592] Udp SetRemoteAddress IP[127.0.0.1], Port[6000]
ThreadID[44592] Udp Init Successed.
helloworld
ThreadID[44592] Udp ZipSendTo: Len:[11], Buff:[helloworld]
ThreadID[44592] Udp SendTo:[127.0.0.1:6000], Len:[19], Ret:[19], Buff:[x薍蜕??蔍a]
[7801cb48cdc9c92fcf2fca496100001b73043d]
test
ThreadID[44592] Udp ZipSendTo: Len:[5], Buff:[test]
ThreadID[44592] Udp SendTo:[127.0.0.1:6000], Len:[13], Ret:[13], Buff:[x+I-.a]
[78012b492d2e610000061e01c1]
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
ThreadID[44592] Udp ZipSendTo: Len:[46], Buff:[zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz]
ThreadID[44592] Udp SendTo:[127.0.0.1:6000], Len:[13], Ret:[13], Buff:[x"0]
[7801abaa220130000002fc1573]

UdpServer输出:

ThreadID[91340] Udp SetBindAddress IP[127.0.0.1], Port[6000]
ThreadID[91340] Udp Init Successed.
ThreadID[91340] Udp RecvFrom:[127.0.0.1:60499], recvLen:[19]
[7801cb48cdc9c92fcf2fca496100001b73043d]
ThreadID[91340] Udp ZipRecvFrom: Len:[11], Buff:[helloworld]
ThreadID[91340] Udp RecvFrom:[127.0.0.1:60499], recvLen:[13]
[78012b492d2e610000061e01c1]
ThreadID[91340] Udp ZipRecvFrom: Len:[5], Buff:[test]
ThreadID[91340] Udp RecvFrom:[127.0.0.1:60499], recvLen:[13]
[7801abaa220130000002fc1573]
ThreadID[91340] Udp ZipRecvFrom: Len:[46], Buff:[zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz]

你可能感兴趣的:(C++,网络通信,udp,tcp/ip,网络协议)