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