C++ 简单的UDP客户端与服务端
.h
#pragma once #ifndef __C_UDP_OBJECT_H__ #define __C_UDP_OBJECT_H__ #define OS_PLATFORM_WIN #include <string> #ifdef OS_PLATFORM_WIN #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #else #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> //#include <sys/un.h> //#include <netdb.h> #endif // !OS_PLATFORM_WIN class CUdpObject { protected: CUdpObject(); virtual ~CUdpObject(); public: virtual void SetParameter(int nPort, const char* szAddress = nullptr); public: virtual int SendTo(const char* szData, int nDataLength); virtual int ReceiveFrom(char* szBuffer, int nBufferSize); public: virtual const std::string& ToString() = 0; protected: virtual struct sockaddr_in& SocketAddress(); protected: #ifdef OS_PLATFORM_WIN SOCKET m_sktUdpObject; #else int m_sktUdpObject; #endif // !OS_PLATFORM_WIN struct sockaddr_in m_sktUdpObjectAddress = { 0 }; volatile int m_nLastSendTransferred = 0; volatile int m_nLastReceiveTransferred = 0; private: int m_nPort = 0; char m_szAddress[32] = { 0 }; private: CUdpObject(const CUdpObject&); CUdpObject& operator=(const CUdpObject&); }; class CUdpClient : public CUdpObject { public: CUdpClient() { m_strEndPoint = "C:" + std::to_string(m_sktUdpObject); printf("ctor %s.\r\n", ToString().c_str()); }; virtual ~CUdpClient() { printf("dctor %s.\r\n", ToString().c_str()); }; public: virtual bool IsConnect(); public: virtual const std::string& ToString() override; private: std::string m_strEndPoint; private: CUdpClient(const CUdpClient&); CUdpClient& operator=(const CUdpClient&); }; //Single Client class CUdpServer : public CUdpObject { public: CUdpServer() { m_strEndPoint = "S:" + std::to_string(m_sktUdpObject); printf("ctor %s.\r\n", ToString().c_str()); }; virtual ~CUdpServer() { printf("dctor %s.\r\n", ToString().c_str()); }; public: void SetParameter(int nPort, const char* szAddress = nullptr) override; public: struct sockaddr_in & SocketAddress() override; public: virtual const std::string& ToString() override; private: struct sockaddr_in m_sktAddressClient = { 0 }; private: std::string m_strEndPoint; private: CUdpServer(const CUdpServer&); CUdpServer& operator=(const CUdpServer&); }; #endif // !__C_UDP_OBJECT_H__
.cpp
#include "UdpObject.h" #include <cstdio> #include <cstdlib> #include <cstring> CUdpObject::CUdpObject() { #ifdef OS_PLATFORM_WIN WSADATA stData; WSAStartup(MAKEWORD(2, 2), &stData); #else #endif // !OS_PLATFORM_WIN m_sktUdpObject = socket(AF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP, IPPROTO_UDPLITE*/); } CUdpObject::~CUdpObject() { #ifdef OS_PLATFORM_WIN closesocket(m_sktUdpObject); WSACleanup(); #else //shutdown(m_sktUdpObject, SHUT_RDWR); close(m_sktUdpObject); #endif // !OS_PLATFORM_WIN } void CUdpObject::SetParameter(int nPort, const char* szAddress) { m_nPort = nPort; m_sktUdpObjectAddress.sin_family = AF_INET; m_sktUdpObjectAddress.sin_port = htons(m_nPort); if (nullptr != szAddress) { std::strcpy(m_szAddress, szAddress); m_sktUdpObjectAddress.sin_addr.s_addr = inet_addr(m_szAddress); } else { m_sktUdpObjectAddress.sin_addr.s_addr = INADDR_ANY; } } struct sockaddr_in& CUdpObject::SocketAddress() { return m_sktUdpObjectAddress; } int CUdpObject::SendTo(const char* szData, int nDataLength) { struct sockaddr_in& sktAddress = SocketAddress(); #ifdef OS_PLATFORM_WIN int nSktAddressSize = sizeof(sktAddress); #else socklen_t nSktAddressSize = sizeof(sktAddress); #endif // !OS_PLATFORM_WIN m_nLastSendTransferred = sendto(m_sktUdpObject, szData, nDataLength, 0, (const struct sockaddr*)&sktAddress, sizeof(sktAddress)); return m_nLastSendTransferred; } int CUdpObject::ReceiveFrom(char* szBuffer, int nBufferSize) { struct sockaddr_in& sktAddress = SocketAddress(); #ifdef OS_PLATFORM_WIN int nSktAddressSize = sizeof(sktAddress); #else socklen_t nSktAddressSize = sizeof(sktAddress); #endif // !OS_PLATFORM_WIN m_nLastReceiveTransferred = recvfrom(m_sktUdpObject, szBuffer, nBufferSize, 0, (struct sockaddr*)&sktAddress, &nSktAddressSize); return m_nLastReceiveTransferred; } bool CUdpClient::IsConnect() { return m_nLastSendTransferred >= 0 || m_nLastReceiveTransferred >= 0; } const std::string& CUdpClient::ToString() { return m_strEndPoint; } void CUdpServer::SetParameter(int nPort, const char* szAddress) { CUdpObject::SetParameter(nPort, nullptr); bind(m_sktUdpObject, (const struct sockaddr*)&m_sktUdpObjectAddress, sizeof(m_sktUdpObjectAddress)); } struct sockaddr_in& CUdpServer::SocketAddress() { return m_sktAddressClient; } const std::string& CUdpServer::ToString() { return m_strEndPoint; }
.test.cpp
#include <cstring> #include <iostream> #include "UdpObject.h" using namespace std; //int cudp_test() int main() { char szBuffer[128] = { 0 }; CUdpServer server; server.SetParameter(60001); { CUdpClient client; client.SetParameter(60001, "192.168.1.76"); std::strcpy(szBuffer, "abcedfe"); std::cout << "Client Send: " << szBuffer << std::endl; client.SendTo(szBuffer, std::strlen(szBuffer)); memset(szBuffer, 0, sizeof(szBuffer)); server.ReceiveFrom(szBuffer, sizeof(szBuffer)); std::cout << "Server Receive : " << szBuffer << std::endl; std::strcpy(szBuffer, "daaaaaaaaaaaaaaaaa"); std::cout << "Server Send: " << szBuffer << std::endl; server.SendTo(szBuffer, std::strlen(szBuffer)); memset(szBuffer, 0, sizeof(szBuffer)); client.ReceiveFrom(szBuffer, sizeof(szBuffer)); std::cout << "Client Receive : " << szBuffer << std::endl; std::cout << client.IsConnect() << std::endl; } { CUdpClient client; client.SetParameter(60001, "192.168.1.76"); std::strcpy(szBuffer, "aassasaassasasasasaaas"); std::cout << "Client Send: " << szBuffer << std::endl; client.SendTo(szBuffer, std::strlen(szBuffer)); memset(szBuffer, 0, sizeof(szBuffer)); server.ReceiveFrom(szBuffer, sizeof(szBuffer)); std::cout << "Server Receive : " << szBuffer << std::endl; std::strcpy(szBuffer, "vdvdvdvdvdvdvdvdvdv"); std::cout << "Server Send: " << szBuffer << std::endl; server.SendTo(szBuffer, std::strlen(szBuffer)); memset(szBuffer, 0, sizeof(szBuffer)); client.ReceiveFrom(szBuffer, sizeof(szBuffer)); std::cout << "Client Receive : " << szBuffer << std::endl; std::cout << client.IsConnect() << std::endl; } std::cout << "Done." << std::endl; getchar(); return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.5) project(upd_test) set(TARGET ${PROJECT_NAME}) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../../Release/) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") add_definitions(-DOS_PLATFORM_UNIX) add_executable(${TARGET} UdpObject.cpp Test_UdpObject.cpp) target_link_libraries(${TARGET})
.build.sh
#! /bin/sh # dirBuildShell="../Temp/" # if [ -d "${dirBuildShell}" ]; then rm -rf "${dirBuildShell}" fi # if [ $# -ge 1 ]; then dirBuildShell="../$1/" rm -rf "${dirBuildShell}" fi # if [ ! -d "${dirBuildShell}" ]; then mkdir "${dirBuildShell}" cd "${dirBuildShell}" fi # cmake ../Test/ && make