29#if defined(TIMEMORY_WINDOWS)
33# include <arpa/inet.h>
35# include <sys/socket.h>
44#include <unordered_map>
51#if defined(TIMEMORY_WINDOWS)
53static constexpr int invalid_socket = INVALID_SOCKET;
54static constexpr int socket_error = SOCKET_ERROR;
57static constexpr int invalid_socket = 0;
58static constexpr int socket_error = -1;
80 template <
typename CallbackT>
82 int64_t _max_packets = 0)
85 if(tim::socket::manager::init() != 0)
87 std::cerr <<
"Can't start socket!" << std::endl;
91 socket_t _listening = ::socket(AF_INET, SOCK_STREAM, 0);
92 if(_listening == invalid_socket)
94 std::cerr <<
"Can't create a socket!" << std::endl;
99 _hint.sin_family = AF_INET;
100 _hint.sin_port = htons(_port);
101#if defined(TIMEMORY_WINDOWS)
102 _hint.sin_addr.S_un.S_addr = INADDR_ANY;
104 _hint.sin_addr.s_addr = INADDR_ANY;
107 ::bind(_listening, (sockaddr*) &_hint,
sizeof(_hint));
111#if defined(TIMEMORY_WINDOWS)
112 int _client_size =
sizeof(_client);
114 unsigned int _client_size =
sizeof(_client);
116 socket_t _client_socket = accept(_listening, (sockaddr*) &_client, &_client_size);
117 m_server_sockets[_channel_name] = _client_socket;
118 char _host[NI_MAXHOST];
119 char _service[NI_MAXSERV];
121 memset(_host, 0, NI_MAXHOST);
122 memset(_service, 0, NI_MAXSERV);
123 if(getnameinfo((sockaddr*) &_client,
sizeof(_client), _host, NI_MAXHOST, _service,
126 std::cout << _host <<
" connected on port " << _service << std::endl;
130 inet_ntop(AF_INET, &_client.sin_addr, _host, NI_MAXHOST);
131 std::cout << _host <<
" connected on port " << ntohs(_client.sin_port)
141 int _bytes_recv = ::recv(_client_socket, _buff,
buffer_size, 0);
144 if(_bytes_recv == socket_error)
146 std::cerr <<
"Error in recv(). Quitting" << std::endl;
153 _nrecv.second += _bytes_recv;
155 if(_max_packets > 0 && _nrecv.first >= _max_packets)
157 std::cerr <<
"Maximum number of packages received: " << _max_packets
158 <<
". Quitting" << std::endl;
169 tim::socket::manager::quit();
175 if(m_client_sockets.find(_channel_name) != m_client_sockets.end())
177 socket_t _sock = m_client_sockets.at(_channel_name);
178 int _send_result =
::send(_sock, _data.c_str(), _data.size() + 1, 0);
179 if(_send_result == socket_error)
181 std::cerr <<
"Can't create socket!" << std::endl;
191 if(tim::socket::manager::init() != 0)
193 std::cerr <<
"Can't start socket!" << std::endl;
197 socket_t _sock = ::socket(AF_INET, SOCK_STREAM, 0);
198 if(_sock == invalid_socket)
200 std::cerr <<
"Can't create socket!" << std::endl;
201 tim::socket::manager::quit();
206 _hint.sin_family = AF_INET;
207 _hint.sin_port = htons(_port);
208 inet_pton(AF_INET, _ip.c_str(), &_hint.sin_addr);
210 int _conn_result =
::connect(_sock, (sockaddr*) &_hint,
sizeof(_hint));
211 if(_conn_result == socket_error)
213 std::cerr <<
"Can't connect to server!" << std::endl;
215 tim::socket::manager::quit();
218 m_client_sockets[_channel_name] = _sock;
224 if(m_client_sockets.find(_channel_name) != m_client_sockets.end())
226 socket_t s = m_client_sockets.at(_channel_name);
228 tim::socket::manager::quit();
237#if defined(TIMEMORY_WINDOWS)
239 return WSAStartup(MAKEWORD(1, 1), &_wsa_data);
247#if defined(TIMEMORY_WINDOWS)
257#if defined(TIMEMORY_WINDOWS)
258 if((status = ::shutdown(_sock, SD_BOTH)) == 0)
259 return ::closesocket(_sock);
261 if((status = ::shutdown(_sock, SHUT_RDWR)) == 0)
auto listen(const std::string &_channel_name, int _port, CallbackT &&callback, int64_t _max_packets=0) -> decltype(callback(_channel_name), listen_info_t{})
listen for data on a socket. Returns a pair of the number of packets received and the number of bytes...
std::pair< int64_t, int64_t > listen_info_t
bool close(const std::string &_channel_name)
static constexpr int buffer_size
bool connect(const std::string &_channel_name, const std::string &_ip, int _port)
manager & operator=(const manager &)=default
std::unordered_map< std::string, socket_t > socket_map_t
manager & operator=(manager &&)=default
bool send(const std::string &_channel_name, const std::string &_data)
manager(manager &&)=default
manager(const manager &)=default
tim::mpl::apply< std::string > string