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> 31 static const int _flags = MSG_NOSIGNAL;
33 static const int _flags = 0;
39 uint32_t m_address = 0;
42 void resolve(
const std::string& address)
47 if (address ==
"255.255.255.255")
51 m_address = INADDR_BROADCAST;
54 else if (address ==
"0.0.0.0")
56 m_address = INADDR_ANY;
63 if (inet_pton(AF_INET, address.c_str(), &addr) == 1)
65 m_address = addr.s_addr;
72 memset(&hints, 0,
sizeof(hints));
73 hints.ai_family = AF_INET;
74 addrinfo* result = NULL;
75 if (getaddrinfo(address.c_str(), NULL, &hints, &result) == 0)
79 addr =
reinterpret_cast<sockaddr_in*
>(result->ai_addr)->sin_addr;
81 m_address = addr.s_addr;
97 return ntohl(m_address);
100 operator bool()
const {
return m_valid; }
107 using SocketTp = int;
109 using SocketTp = SOCKET;
111 SocketTp m_socket = -1;
114 static sockaddr_in createAddress(uint32_t address,
unsigned short port)
117 memset(&addr, 0,
sizeof(addr));
118 addr.sin_addr.s_addr = htonl(address);
119 addr.sin_family = AF_INET;
120 addr.sin_port = htons(port);
123 addr.sin_len =
sizeof(addr);
134 m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
137 fprintf(stderr,
"Can't allocate socket\n");
142 setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&one),
sizeof(one));
144 setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char*>(&one),
sizeof(one));
147 setBlocking(m_isBlocking);
152 void setRemoteSocket(
int remSocket)
155 m_socket = remSocket;
156 setBlocking(m_isBlocking);
170 switch (WSAGetLastError())
174 return EResult::Busy;
176 return EResult::Error;
182 : m_isBlocking(blocking) {}
188 : m_socket(other.m_socket), m_isBlocking(other.m_isBlocking)
195 m_socket = other.m_socket;
197 m_isBlocking = other.m_isBlocking;
203 m_isBlocking = blocking;
205 int status = fcntl(m_socket, F_GETFL);
207 fcntl(m_socket, F_SETFL, status & ~O_NONBLOCK);
209 fcntl(m_socket, F_SETFL, status | O_NONBLOCK);
211 u_long b = blocking ? 0 : 1;
212 ioctlsocket(m_socket, FIONBIO, &b);
216 bool isOpen()
const {
return m_socket != -1; }
222 sockaddr_in addr = createAddress(address.
toInteger(), port);
223 if (bind(m_socket, reinterpret_cast<sockaddr*>(&addr),
sizeof(addr)) == -1)
226 fprintf(stderr,
"Failed to bind listener socket to port %d\n", port);
230 if (::listen(m_socket, 0) == -1)
233 fprintf(stderr,
"Failed to listen to port %d\n", port);
243 return EResult::Error;
246 socklen_t length =
sizeof(sockaddr_in);
247 int remoteSocket = ::accept(m_socket, reinterpret_cast<sockaddr*>(&fromAddress), &length);
250 if (remoteSocket == -1)
253 EResult res = (errno == EAGAIN) ? EResult::Busy : EResult::Error;
254 if (res == EResult::Error)
255 fprintf(stderr,
"Failed to accept incoming connection: %s\n", strerror(errno));
258 if (res == EResult::Error)
259 fprintf(stderr,
"Failed to accept incoming connection\n");
265 remoteSocketOut.setRemoteSocket(remoteSocket);
272 sockaddr_in fromAddress;
273 return accept(remoteSocketOut, fromAddress);
278 sockaddr_in fromAddress;
279 socklen_t len =
sizeof(fromAddress);
280 char name[NI_MAXHOST];
281 EResult res = accept(remoteSocketOut, fromAddress);
282 if (res == EResult::OK)
283 if (getnameinfo((sockaddr*)&fromAddress, len, name, NI_MAXHOST,
nullptr, 0, 0) == 0)
284 fromHostname.assign(name);
295 closesocket(m_socket);
304 return EResult::Error;
307 return EResult::Error;
311 for (
size_t sent = 0; sent < len; sent += result)
314 result = ::send(m_socket, static_cast<const char*>(buf) + sent, len - sent, _flags);
319 return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
321 return LastWSAError();
332 return send(buf, len, transferred);
339 return EResult::Error;
342 return EResult::Error;
348 int result = ::recv(m_socket, static_cast<char*>(buf), static_cast<int>(len), _flags);
352 return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
354 return LastWSAError();
356 else if (result == 0)
357 return EResult::Error;
359 transferred = result;
366 return recv(buf, len, transferred);
369 operator bool()
const {
return isOpen(); }
377 #endif // JBUS_SOCKET_HPP SocketTp GetInternalSocket() const
Definition: Socket.hpp:371
EResult send(const void *buf, size_t len, size_t &transferred)
Definition: Socket.hpp:300
bool openAndListen(const IPAddress &address, uint32_t port)
Definition: Socket.hpp:217
EResult recv(void *buf, size_t len)
Definition: Socket.hpp:363
Definition: Socket.hpp:104
bool isOpen() const
Definition: Socket.hpp:216
EResult recv(void *buf, size_t len, size_t &transferred)
Definition: Socket.hpp:335
void close()
Definition: Socket.hpp:288
~Socket()
Definition: Socket.hpp:183
Definition: Socket.hpp:37
Socket & operator=(Socket &&other)
Definition: Socket.hpp:192
EResult accept(Socket &remoteSocketOut)
Definition: Socket.hpp:270
uint32_t toInteger() const
Definition: Socket.hpp:95
Socket(Socket &&other)
Definition: Socket.hpp:187
EResult send(const void *buf, size_t len)
Definition: Socket.hpp:329
EResult accept(Socket &remoteSocketOut, sockaddr_in &fromAddress)
Definition: Socket.hpp:240
EResult
Definition: Socket.hpp:160
Socket(bool blocking)
Definition: Socket.hpp:181
void setBlocking(bool blocking)
Definition: Socket.hpp:201
EResult accept(Socket &remoteSocketOut, std::string &fromHostname)
Definition: Socket.hpp:276
IPAddress(const std::string &address)
Definition: Socket.hpp:90