Cleanup windows udp client
This commit is contained in:
		@@ -3,16 +3,12 @@
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifndef WIN32_LEAN_AND_MEAN
 | 
			
		||||
#define WIN32_LEAN_AND_MEAN
 | 
			
		||||
#endif  // WIN32_LEAN_AND_MEAN
 | 
			
		||||
// udp client helper
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <spdlog/common.h>
 | 
			
		||||
#include <spdlog/details/os.h>
 | 
			
		||||
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
#include <spdlog/details/windows_include.h>
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <ws2tcpip.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@@ -26,28 +22,14 @@ namespace spdlog {
 | 
			
		||||
namespace details {
 | 
			
		||||
class udp_client
 | 
			
		||||
{
 | 
			
		||||
    const int TX_BUFFER_SIZE = 10240;
 | 
			
		||||
    static constexpr int TX_BUFFER_SIZE = 1024*10;
 | 
			
		||||
    SOCKET socket_ = INVALID_SOCKET;
 | 
			
		||||
    sockaddr_in addr_ = {0};
 | 
			
		||||
 | 
			
		||||
    static bool winsock_initialized_()
 | 
			
		||||
    {
 | 
			
		||||
        SOCKET s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
 | 
			
		||||
        if (s == INVALID_SOCKET)
 | 
			
		||||
        {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            closesocket(s);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void init_winsock_()
 | 
			
		||||
    {
 | 
			
		||||
        WSADATA wsaData;
 | 
			
		||||
        auto rv = WSAStartup(MAKEWORD(2, 2), &wsaData);
 | 
			
		||||
        auto rv = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
 | 
			
		||||
        if (rv != 0)
 | 
			
		||||
        {
 | 
			
		||||
            throw_winsock_error_("WSAStartup failed", ::WSAGetLastError());
 | 
			
		||||
@@ -63,52 +45,46 @@ class udp_client
 | 
			
		||||
        throw_spdlog_ex(fmt::format("udp_sink - {}: {}", msg, buf));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    bool is_init() const
 | 
			
		||||
    void cleanup_()
 | 
			
		||||
    {
 | 
			
		||||
        return socket_ != INVALID_SOCKET;
 | 
			
		||||
        if (socket_ != INVALID_SOCKET)
 | 
			
		||||
        {
 | 
			
		||||
            ::closesocket(socket_);
 | 
			
		||||
        }
 | 
			
		||||
        socket_ = INVALID_SOCKET;
 | 
			
		||||
        ::WSACleanup();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool init(const std::string &host, uint16_t port)
 | 
			
		||||
    {
 | 
			
		||||
        // initialize winsock if needed
 | 
			
		||||
        if (!winsock_initialized_())
 | 
			
		||||
public:
 | 
			
		||||
    udp_client(const std::string &host, uint16_t port)
 | 
			
		||||
    {
 | 
			
		||||
        init_winsock_();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        addr_.sin_family = PF_INET;
 | 
			
		||||
        addr_.sin_port = htons(port);
 | 
			
		||||
        addr_.sin_addr.s_addr = INADDR_ANY;
 | 
			
		||||
        InetPton(PF_INET, TEXT(host.c_str()), &addr_.sin_addr.s_addr);
 | 
			
		||||
 | 
			
		||||
        socket_ = socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
        socket_ = ::socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
        if (socket_ == INVALID_SOCKET)
 | 
			
		||||
        {
 | 
			
		||||
            int last_error = ::WSAGetLastError();
 | 
			
		||||
            WSACleanup();
 | 
			
		||||
            ::WSACleanup();
 | 
			
		||||
            throw_winsock_error_("error: Create Socket failed", last_error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int option_value = TX_BUFFER_SIZE;
 | 
			
		||||
        if (setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, (char*)&option_value, sizeof(option_value)) < 0)
 | 
			
		||||
        if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0)
 | 
			
		||||
        {
 | 
			
		||||
            int last_error = ::WSAGetLastError();
 | 
			
		||||
            close();
 | 
			
		||||
            cleanup_();
 | 
			
		||||
            throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void close()
 | 
			
		||||
    ~udp_client()
 | 
			
		||||
    {
 | 
			
		||||
        if (socket_ != -1)
 | 
			
		||||
        {
 | 
			
		||||
            ::closesocket(socket_);
 | 
			
		||||
        }
 | 
			
		||||
        socket_ = INVALID_SOCKET;
 | 
			
		||||
        WSACleanup();
 | 
			
		||||
        cleanup_();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SOCKET fd() const
 | 
			
		||||
@@ -116,22 +92,14 @@ public:
 | 
			
		||||
        return socket_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~udp_client()
 | 
			
		||||
    {
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void send(const char *data, size_t n_bytes)
 | 
			
		||||
    {
 | 
			
		||||
        socklen_t tolen = sizeof(struct sockaddr);
 | 
			
		||||
        if (sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1)
 | 
			
		||||
        if (::sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1)
 | 
			
		||||
        {
 | 
			
		||||
            close();
 | 
			
		||||
            throw_spdlog_ex("sendto(2) failed", errno);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
} // namespace details
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
#endif  // _WIN32
 | 
			
		||||
 
 | 
			
		||||
@@ -41,10 +41,8 @@ public:
 | 
			
		||||
    // host can be hostname or ip address
 | 
			
		||||
 | 
			
		||||
    explicit udp_sink(udp_sink_config sink_config)
 | 
			
		||||
        : config_{std::move(sink_config)}
 | 
			
		||||
    {
 | 
			
		||||
        client_.init(config_.server_host, config_.server_port);
 | 
			
		||||
    }
 | 
			
		||||
        : client_{sink_config.server_host, sink_config.server_port}
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    ~udp_sink() override = default;
 | 
			
		||||
 | 
			
		||||
@@ -57,7 +55,6 @@ protected:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void flush_() override {}    
 | 
			
		||||
    udp_sink_config config_;
 | 
			
		||||
    details::udp_client client_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user