C++之基于Winsock2封装UDPServer与UDPClient

文章目录

    • Socket过程
    • UDPServer.h
    • UDPServer.cpp
    • UDPClient.h
    • UDPClient.cpp
    • main.cpp
    • CMakeLists.txt
    • 测试截图

Socket过程

  • UDPServer

C++之基于Winsock2封装UDPServer与UDPClient_第1张图片

  • UDPClient

C++之基于Winsock2封装UDPServer与UDPClient_第2张图片

UDPServer.h

#ifndef UDPSERVER_H_INCLUDED
#define UDPSERVER_H_INCLUDED

#include 
#include 
#include 

class UDPServer
{
private:
    WORD sockVersion;
    WSADATA wsaData;
    SOCKET udpSocket;
    sockaddr_in localAddr;
    sockaddr_in remoteAddr; // Client
    const int MSG_SIZE = 1024;

public:
    UDPServer();
    ~UDPServer();
    void Bind(u_short port);
    void Receive();
    bool Send(std::string message);
};

#endif // UDPSERVER_H_INCLUDED

UDPServer.cpp

#include "UDPServer.h"

UDPServer::UDPServer()
{
    sockVersion = MAKEWORD(2, 2);
    WSAStartup(sockVersion, &wsaData);
    udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}

UDPServer::~UDPServer()
{
    closesocket(udpSocket);
    WSACleanup();
}

void UDPServer::Bind(u_short port)
{
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(port);
    // localAddr.sin_addr.S_un.S_addr = INADDR_ANY; // 0.0.0.0
    localAddr.sin_addr.S_un.S_addr = inet_addr("0.0.0.0");
    bind(udpSocket, (const sockaddr *)&localAddr, sizeof(localAddr));
}

void UDPServer::Receive()
{
    while (true)
    {
        char recvBuffer[MSG_SIZE];
        int localAddrSize = sizeof(localAddr);
        int lenRemoteAddr = sizeof(remoteAddr);
        int len = recvfrom(udpSocket, recvBuffer, MSG_SIZE, 0, (SOCKADDR *)&remoteAddr, &lenRemoteAddr);
        if (len > 0)
        {
            recvBuffer[len] = '\0';
            std::cout << "[" << inet_ntoa(remoteAddr.sin_addr) << ":" << remoteAddr.sin_port << "] -> " << recvBuffer << std::endl;
        }
    }
}

bool UDPServer::Send(std::string message)
{
    int ret = sendto(udpSocket, message.c_str(), message.length(), 0, (sockaddr *)&remoteAddr, sizeof(remoteAddr));
    if (ret == SOCKET_ERROR)
    {
        return false;
    }
    else
    {
        return true;
    }
}

UDPClient.h

#ifndef UDPCLIENT_H_INCLUDED
#define UDPCLIENT_H_INCLUDED

#include 
#include 
#include 

class UDPClient
{
private:
    WORD sockVersion;
    WSADATA wsaData;
    SOCKET udpSocket;
    sockaddr_in localAddr;
    sockaddr_in remoteAddr; // Client
    const int MSG_SIZE = 1024;

public:
    UDPClient();
    ~UDPClient();
    void Bind(std::string ip, u_short port);
    void Receive();
    bool Send(std::string message);
};

#endif // UDPCLIENT_H_INCLUDED

UDPClient.cpp

#include "UDPClient.h"

UDPClient::UDPClient()
{
    sockVersion = MAKEWORD(2, 2);
    WSAStartup(sockVersion, &wsaData);
    udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}

UDPClient::~UDPClient()
{
    closesocket(udpSocket);
    WSACleanup();
}

void UDPClient::Bind(std::string ip, u_short port)
{
    localAddr.sin_family = AF_INET;
    localAddr.sin_port = htons(port);
    localAddr.sin_addr.S_un.S_addr = INADDR_ANY; // 0.0.0.0
    remoteAddr = localAddr;
    remoteAddr.sin_addr.S_un.S_addr = inet_addr(ip.c_str());
    bind(udpSocket, (const sockaddr *)&localAddr, sizeof(localAddr));
    Send("Hello");
}

void UDPClient::Receive()
{
    while (true)
    {
        char recvBuffer[MSG_SIZE];
        int localAddrSize = sizeof(localAddr);
        int lenRemoteAddr = sizeof(remoteAddr);
        int len = recvfrom(udpSocket, recvBuffer, MSG_SIZE, 0, (SOCKADDR *)&remoteAddr, &lenRemoteAddr);
        if (len > 0)
        {
            recvBuffer[len] = '\0';
            std::cout << "[" << inet_ntoa(remoteAddr.sin_addr) << ":" << remoteAddr.sin_port << "] -> " << recvBuffer << std::endl;
        }
    }
}

bool UDPClient::Send(std::string message)
{
    int ret = sendto(udpSocket, message.c_str(), message.length(), 0, (sockaddr *)&remoteAddr, sizeof(remoteAddr));
    if (ret == SOCKET_ERROR)
    {
        return false;
    }
    else
    {
        return true;
    }
}

main.cpp

#include 
#include 
#include 

#include "UDPClient.h"
#include "UDPServer.h"

int main()
{
    std::cout << "[0] -> UDPServer"
              << "\n"
              << "[1] -> UDPClient" << std::endl;
    u_int flag = 2;
    std::cin >> flag;

    switch (flag)
    {
    case 0:
    {
        std::cout << "[UDPServer] -> Start" << std::endl;
        UDPServer udpServer;
        udpServer.Bind(6789);
        std::thread recvThread(&UDPServer::Receive, &udpServer);

        // 主线程
        while (true)
        {
            std::cout << "\n[Input] -> ";
            std::string msg;
            std::cin >> msg;
            if (udpServer.Send(msg))
            {
                std::cout << "[UDPServer] -> " << msg << std::endl;
            }
            else
            {
                std::cout << "[ErrorCode] -> " << GetLastError() << std::endl;
            }
        }

        // 等待线程结束
        recvThread.join();

        std::cout << "[UDPServer] -> Stop" << std::endl;
        break;
    }
    case 1:
    {
        std::cout << "[UDPClient] -> Start" << std::endl;
        UDPClient udpClient;
        udpClient.Bind("127.0.0.1", 6789);
        std::thread recvThread(&UDPClient::Receive, &udpClient);

        // 主线程
        while (true)
        {
            std::cout << "\n[Input] -> ";
            std::string msg;
            std::cin >> msg;
            if (udpClient.Send(msg))
            {
                std::cout << "[UDPClient] -> " << msg << std::endl;
            }
            else
            {
                std::cout << "[ErrorCode] -> " << GetLastError() << std::endl;
            }
        }

        // 等待线程结束
        recvThread.join();

        std::cout << "[UDPClient] -> Stop" << std::endl;
        break;
    }

    default:
        break;
    }

    system("pause");
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(UDPProtocol VERSION 0.1.0 LANGUAGES CXX)

add_executable(${PROJECT_NAME} 
    UDPClient.cpp
    UDPServer.cpp
    main.cpp)

if(WIN32)
    target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32)
endif()

测试截图

C++之基于Winsock2封装UDPServer与UDPClient_第3张图片

你可能感兴趣的:(C++,c++,winsock,udp,server,client)