How do I receive udp packets with winsock in c++?

后端 未结 2 1401
礼貌的吻别
礼貌的吻别 2020-12-28 09:43

As an attempt at wrapping my head around udp sockets I\'ve tried to port the code from this tutorial page http://www.linuxhowtos.org/C_C++/socket.htm to winsock (running on

2条回答
  •  无人及你
    2020-12-28 10:12

    The following UDP test application works correctly on my setup - Windows 7, VS 2013.

    I created some light-weight wrapper classes to do resource management, and turns error codes into exceptions. This makes the client and server code easier to read. Please be sure to run the server first.

    Network.h

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #pragma once
    
    class WSASession
    {
    public:
        WSASession()
        {
            int ret = WSAStartup(MAKEWORD(2, 2), &data);
            if (ret != 0)
                throw std::system_error(WSAGetLastError(), std::system_category(), "WSAStartup Failed");
        }
        ~WSASession()
        {
            WSACleanup();
        }
    private:
        WSAData data;
    };
    
    class UDPSocket
    {
    public:
        UDPSocket()
        {
            sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
            if (sock == INVALID_SOCKET)
                throw std::system_error(WSAGetLastError(), std::system_category(), "Error opening socket");
        }
        ~UDPSocket()
        {
            closesocket(sock);
        }
    
        void SendTo(const std::string& address, unsigned short port, const char* buffer, int len, int flags = 0)
        {
            sockaddr_in add;
            add.sin_family = AF_INET;
            add.sin_addr.s_addr = inet_addr(address.c_str());
            add.sin_port = htons(port);
            int ret = sendto(sock, buffer, len, flags, reinterpret_cast(&add), sizeof(add));
            if (ret < 0)
                throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
        }
        void SendTo(sockaddr_in& address, const char* buffer, int len, int flags = 0)
        {
            int ret = sendto(sock, buffer, len, flags, reinterpret_cast(&address), sizeof(address));
            if (ret < 0)
                throw std::system_error(WSAGetLastError(), std::system_category(), "sendto failed");
        }
        sockaddr_in RecvFrom(char* buffer, int len, int flags = 0)
        {
            sockaddr_in from;
            int size = sizeof(from);
            int ret = recvfrom(sock, buffer, len, flags, reinterpret_cast(&from), &size);
            if (ret < 0)
                throw std::system_error(WSAGetLastError(), std::system_category(), "recvfrom failed");
    
            // make the buffer zero terminated
            buffer[ret] = 0;
            return from;
        }
        void Bind(unsigned short port)
        {
            sockaddr_in add;
            add.sin_family = AF_INET;
            add.sin_addr.s_addr = htonl(INADDR_ANY);
            add.sin_port = htons(port);
    
            int ret = bind(sock, reinterpret_cast(&add), sizeof(add));
            if (ret < 0)
                throw std::system_error(WSAGetLastError(), std::system_category(), "Bind failed");
        }
    
    private:
        SOCKET sock;
    };
    

    Server

    #include "Network.h"
    
    int main()
    {
        try
        {
            WSASession Session;
            UDPSocket Socket;
            char buffer[100];
    
            Socket.Bind(100);
            while (1)
            {
                sockaddr_in add = Socket.RecvFrom(buffer, sizeof(buffer));
    
                std::string input(buffer);
                std::reverse(std::begin(input), std::end(input));
                Socket.SendTo(add, input.c_str(), input.size());
            }
        }
        catch (std::system_error& e)
        {
            std::cout << e.what();
        }
    }
    

    Client

    #include "Network.h"
    
    int main()
    {
        try
        {
            WSASession Session;
            UDPSocket Socket;
            std::string data = "hello world";
            char buffer[100];
    
            Socket.SendTo("127.0.0.1", 100, data.c_str(), data.size());
            Socket.RecvFrom(buffer, 100);
            std::cout << buffer;
        }
        catch (std::exception &ex)
        {
            std::cout << ex.what();
        }
        char c;
        std::cin >> c;
    }
    

提交回复
热议问题