1 #ifndef JBUS_SOCKET_HPP 2 #define JBUS_SOCKET_HPP 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 #include <netinet/tcp.h> 17 #include <sys/types.h> 30 static const int _flags = MSG_NOSIGNAL;
32 static const int _flags = 0;
38 uint32_t m_address = 0;
41 void resolve(
const std::string& address)
46 if (address ==
"255.255.255.255")
50 m_address = INADDR_BROADCAST;
53 else if (address ==
"0.0.0.0")
55 m_address = INADDR_ANY;
62 if (inet_pton(AF_INET, address.c_str(), &addr) == 1)
64 m_address = addr.s_addr;
71 memset(&hints, 0,
sizeof(hints));
72 hints.ai_family = AF_INET;
73 addrinfo* result = NULL;
74 if (getaddrinfo(address.c_str(), NULL, &hints, &result) == 0)
78 addr =
reinterpret_cast<sockaddr_in*
>(result->ai_addr)->sin_addr;
80 m_address = addr.s_addr;
96 return ntohl(m_address);
99 operator bool()
const {
return m_valid; }
106 using SocketTp = int;
108 using SocketTp = SOCKET;
110 SocketTp m_socket = -1;
113 static sockaddr_in createAddress(uint32_t address,
unsigned short port)
116 memset(&addr, 0,
sizeof(addr));
117 addr.sin_addr.s_addr = htonl(address);
118 addr.sin_family = AF_INET;
119 addr.sin_port = htons(port);
122 addr.sin_len =
sizeof(addr);
133 m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
136 fprintf(stderr,
"Can't allocate socket\n");
141 setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&one),
sizeof(one));
143 setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char*>(&one),
sizeof(one));
146 setBlocking(m_isBlocking);
151 void setRemoteSocket(
int remSocket)
154 m_socket = remSocket;
155 setBlocking(m_isBlocking);
169 switch (WSAGetLastError())
173 return EResult::Busy;
175 return EResult::Error;
181 : m_isBlocking(blocking) {}
187 : m_socket(other.m_socket), m_isBlocking(other.m_isBlocking)
194 m_socket = other.m_socket;
196 m_isBlocking = other.m_isBlocking;
202 m_isBlocking = blocking;
204 int status = fcntl(m_socket, F_GETFL);
206 fcntl(m_socket, F_SETFL, status & ~O_NONBLOCK);
208 fcntl(m_socket, F_SETFL, status | O_NONBLOCK);
210 u_long b = blocking ? 0 : 1;
211 ioctlsocket(m_socket, FIONBIO, &b);
215 bool isOpen()
const {
return m_socket != -1; }
221 sockaddr_in addr = createAddress(address.
toInteger(), port);
222 if (bind(m_socket, reinterpret_cast<sockaddr*>(&addr),
sizeof(addr)) == -1)
225 fprintf(stderr,
"Failed to bind listener socket to port %d\n", port);
229 if (::listen(m_socket, 0) == -1)
232 fprintf(stderr,
"Failed to listen to port %d\n", port);
242 return EResult::Error;
245 socklen_t length =
sizeof(sockaddr_in);
246 int remoteSocket = ::accept(m_socket, reinterpret_cast<sockaddr*>(&fromAddress), &length);
249 if (remoteSocket == -1)
252 EResult res = (errno == EAGAIN) ? EResult::Busy : EResult::Error;
253 if (res == EResult::Error)
254 fprintf(stderr,
"Failed to accept incoming connection: %s\n", strerror(errno));
257 if (res == EResult::Error)
258 fprintf(stderr,
"Failed to accept incoming connection\n");
264 remoteSocketOut.setRemoteSocket(remoteSocket);
271 sockaddr_in fromAddress;
272 return accept(remoteSocketOut, fromAddress);
277 sockaddr_in fromAddress;
278 socklen_t len =
sizeof(fromAddress);
279 char name[NI_MAXHOST];
280 EResult res = accept(remoteSocketOut, fromAddress);
281 if (res == EResult::OK)
282 if (getnameinfo((sockaddr*)&fromAddress, len, name, NI_MAXHOST,
nullptr, 0, 0) == 0)
283 fromHostname.assign(name);
294 closesocket(m_socket);
303 return EResult::Error;
306 return EResult::Error;
310 for (
size_t sent = 0; sent < len; sent += result)
313 result = ::send(m_socket, static_cast<const char*>(buf) + sent, len - sent, _flags);
318 return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
320 return LastWSAError();
331 return send(buf, len, transferred);
338 return EResult::Error;
341 return EResult::Error;
347 int result = ::recv(m_socket, static_cast<char*>(buf), static_cast<int>(len), _flags);
351 return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
353 return LastWSAError();
355 else if (result == 0)
356 return EResult::Error;
358 transferred = result;
365 return recv(buf, len, transferred);
368 operator bool()
const {
return isOpen(); }
376 #endif // JBUS_SOCKET_HPP SocketTp GetInternalSocket() const
Definition: Socket.hpp:370
EResult send(const void *buf, size_t len, size_t &transferred)
Definition: Socket.hpp:299
bool openAndListen(const IPAddress &address, uint32_t port)
Definition: Socket.hpp:216
EResult recv(void *buf, size_t len)
Definition: Socket.hpp:362
Definition: Socket.hpp:103
bool isOpen() const
Definition: Socket.hpp:215
EResult recv(void *buf, size_t len, size_t &transferred)
Definition: Socket.hpp:334
void close()
Definition: Socket.hpp:287
~Socket()
Definition: Socket.hpp:182
Definition: Socket.hpp:36
Socket & operator=(Socket &&other)
Definition: Socket.hpp:191
EResult accept(Socket &remoteSocketOut)
Definition: Socket.hpp:269
uint32_t toInteger() const
Definition: Socket.hpp:94
Socket(Socket &&other)
Definition: Socket.hpp:186
EResult send(const void *buf, size_t len)
Definition: Socket.hpp:328
EResult accept(Socket &remoteSocketOut, sockaddr_in &fromAddress)
Definition: Socket.hpp:239
EResult
Definition: Socket.hpp:159
Socket(bool blocking)
Definition: Socket.hpp:180
void setBlocking(bool blocking)
Definition: Socket.hpp:200
EResult accept(Socket &remoteSocketOut, std::string &fromHostname)
Definition: Socket.hpp:275
IPAddress(const std::string &address)
Definition: Socket.hpp:89