对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] = ' '; 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" #includeusing 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]



