Agora  1.2.0
Agora project
udp_client-windows.h
Go to the documentation of this file.
1 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
3 
4 #pragma once
5 
6 // Helper RAII over winsock udp client socket.
7 // Will throw on construction if socket creation failed.
8 
9 #include <spdlog/common.h>
10 #include <spdlog/details/os.h>
12 #include <winsock2.h>
13 #include <ws2tcpip.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string>
17 
18 #pragma comment(lib, "Ws2_32.lib")
19 #pragma comment(lib, "Mswsock.lib")
20 #pragma comment(lib, "AdvApi32.lib")
21 
22 namespace spdlog {
23 namespace details {
25 {
26  static constexpr int TX_BUFFER_SIZE = 1024 * 10;
27  SOCKET socket_ = INVALID_SOCKET;
28  sockaddr_in addr_ = {0};
29 
30  static void init_winsock_()
31  {
32  WSADATA wsaData;
33  auto rv = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
34  if (rv != 0)
35  {
36  throw_winsock_error_("WSAStartup failed", ::WSAGetLastError());
37  }
38  }
39 
40  static void throw_winsock_error_(const std::string &msg, int last_error)
41  {
42  char buf[512];
43  ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error,
44  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL);
45 
46  throw_spdlog_ex(fmt_lib::format("udp_sink - {}: {}", msg, buf));
47  }
48 
49  void cleanup_()
50  {
51  if (socket_ != INVALID_SOCKET)
52  {
53  ::closesocket(socket_);
54  }
55  socket_ = INVALID_SOCKET;
56  ::WSACleanup();
57  }
58 
59 public:
60  udp_client(const std::string &host, uint16_t port)
61  {
62  init_winsock_();
63 
64  addr_.sin_family = PF_INET;
65  addr_.sin_port = htons(port);
66  addr_.sin_addr.s_addr = INADDR_ANY;
67  if (InetPtonA(PF_INET, host.c_str(), &addr_.sin_addr.s_addr) != 1)
68  {
69  int last_error = ::WSAGetLastError();
70  ::WSACleanup();
71  throw_winsock_error_("error: Invalid address!", last_error);
72  }
73 
74  socket_ = ::socket(PF_INET, SOCK_DGRAM, 0);
75  if (socket_ == INVALID_SOCKET)
76  {
77  int last_error = ::WSAGetLastError();
78  ::WSACleanup();
79  throw_winsock_error_("error: Create Socket failed", last_error);
80  }
81 
82  int option_value = TX_BUFFER_SIZE;
83  if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0)
84  {
85  int last_error = ::WSAGetLastError();
86  cleanup_();
87  throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error);
88  }
89  }
90 
92  {
93  cleanup_();
94  }
95 
96  SOCKET fd() const
97  {
98  return socket_;
99  }
100 
101  void send(const char *data, size_t n_bytes)
102  {
103  socklen_t tolen = sizeof(struct sockaddr);
104  if (::sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1)
105  {
106  throw_spdlog_ex("sendto(2) failed", errno);
107  }
108  }
109 };
110 } // namespace details
111 } // namespace spdlog
spdlog::details::udp_client::init_winsock_
static void init_winsock_()
Definition: udp_client-windows.h:30
windows_include.h
spdlog::details::udp_client::throw_winsock_error_
static void throw_winsock_error_(const std::string &msg, int last_error)
Definition: udp_client-windows.h:40
spdlog::details::udp_client::~udp_client
~udp_client()
Definition: udp_client-windows.h:91
spdlog::details::udp_client::socket_
SOCKET socket_
Definition: udp_client-windows.h:27
spdlog::details::udp_client::fd
SOCKET fd() const
Definition: udp_client-windows.h:96
spdlog::details::udp_client::TX_BUFFER_SIZE
static constexpr int TX_BUFFER_SIZE
Definition: udp_client-windows.h:26
spdlog::details::udp_client
Definition: udp_client-windows.h:24
spdlog::details::udp_client::addr_
sockaddr_in addr_
Definition: udp_client-windows.h:28
spdlog
Definition: async.h:25
spdlog::throw_spdlog_ex
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition: common-inl.h:72
os.h
spdlog::details::udp_client::send
void send(const char *data, size_t n_bytes)
Definition: udp_client-windows.h:101
extract_version.data
dictionary data
Definition: extract_version.py:8
common.h
spdlog::details::udp_client::cleanup_
void cleanup_()
Definition: udp_client-windows.h:49
spdlog::details::udp_client::udp_client
udp_client(const std::string &host, uint16_t port)
Definition: udp_client-windows.h:60
utils::format
std::string format(const T &value)
Definition: utils.h:15