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

Socket过程

  • UDPServer

  • UDPClient

UDPServer.h

#ifndef UDPSERVER_H_INCLUDED
#define UDPSERVER_H_INCLUDED

#include <iostream>
#include <string>
#include <Winsock2.h>

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 <iostream>
#include <string>
#include <Winsock2.h>

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 <iostream>
#include <thread>
#include <string>

#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()

测试截图

猜你喜欢

转载自blog.csdn.net/a924282761/article/details/133877426
今日推荐