对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]