12 # include <winsock2.h> 13 # include <ws2tcpip.h> 33 # define EAGAIN WSATRY_AGAIN 34 # define EINTR WSAEINTR 35 # define EINPROGRESS WSAEINPROGRESS 36 # define EWOULDBLOCK WSAEWOULDBLOCK 37 # define ETIMEDOUT WSAETIMEDOUT 42 # include <sys/types.h> 43 # include <sys/socket.h> 44 # include <netinet/in.h> 50 # include <arpa/inet.h> 57 #if defined(__APPLE__) || defined(__MACH__) 59 # define MSG_NOSIGNAL SO_NOSIGPIPE 73 static bool wsInit =
false;
76 WORD wVersionRequested = MAKEWORD( 2, 0 );
78 WSAStartup(wVersionRequested, &wsaData);
95 return (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK || err == EINTR);
110 #if defined(_WINDOWS) 123 #if defined(_WINDOWS) 124 unsigned long flag = 1;
125 return (ioctlsocket((SOCKET)fd, FIONBIO, &flag) == 0);
127 return (fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
137 return (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (
const char *)&sflag,
sizeof(sflag)) == 0);
147 memset(&ss, 0,
sizeof(ss));
151 sockaddr_in6 *address = (sockaddr_in6 *)&ss;
152 ss_len =
sizeof(sockaddr_in6);
154 address->sin6_family = AF_INET6;
155 address->sin6_addr = in6addr_any;
156 address->sin6_port = htons((u_short) port);
160 sockaddr_in *address = (sockaddr_in *)&ss;
161 ss_len =
sizeof(sockaddr_in);
163 address->sin_family = AF_INET;
164 address->sin_addr.s_addr = htonl(INADDR_ANY);
165 address->sin_port = htons((u_short) port);
168 return (::
bind(fd, (sockaddr*)&ss, ss_len) == 0);
176 return (::
listen(fd, backlog) == 0);
183 struct sockaddr_in addr;
184 #if defined(_WINDOWS) 189 addrlen =
sizeof(addr);
193 return (
int)
::accept(fd, (
struct sockaddr*)&addr, &addrlen);
204 memset(&ss, 0,
sizeof(ss));
206 struct addrinfo* addr;
207 struct addrinfo hints;
208 memset(&hints, 0,
sizeof(hints));
209 hints.ai_family = AF_UNSPEC;
210 if (getaddrinfo(host.c_str(), NULL, &hints, &addr) != 0)
212 fprintf(stderr,
"Couldn't find an %s address for [%s]\n",
s_use_ipv6_ ?
"AF_INET6" :
"AF_INET", host.c_str());
217 struct addrinfo* it = addr;
219 for (; it; it = it->ai_next)
223 sockaddr_in *address = (sockaddr_in *)&ss;
224 ss_len =
sizeof(sockaddr_in);
226 memcpy(address, it->ai_addr, it->ai_addrlen);
227 address->sin_family = it->ai_family;
228 address->sin_port = htons((u_short) port);
230 XmlRpcUtil::log(5,
"found host as %s\n", inet_ntoa(address->sin_addr));
236 sockaddr_in6 *address = (sockaddr_in6 *)&ss;
237 ss_len =
sizeof(sockaddr_in6);
239 memcpy(address, it->ai_addr, it->ai_addrlen);
240 address->sin6_family = it->ai_family;
241 address->sin6_port = htons((u_short) port);
245 XmlRpcUtil::log(5,
"found ipv6 host as %s\n", inet_ntop(AF_INET6, (
void*)&(address->sin6_addr), buf,
sizeof(buf)));
254 printf(
"Couldn't find an %s address for [%s]\n",
s_use_ipv6_ ?
"AF_INET6" :
"AF_INET", host.c_str());
261 int result =
::connect(fd, (sockaddr*)&ss, ss_len);
264 if ( (error != EINPROGRESS) && error != EWOULDBLOCK) {
265 printf(
"::connect error = %d\n",
getError());
280 const int READ_SIZE = 4096;
281 char readBuf[READ_SIZE];
283 bool wouldBlock =
false;
286 while ( ! wouldBlock && ! *eof) {
287 #if defined(_WINDOWS) 288 int n = recv(fd, readBuf, READ_SIZE-1, 0);
290 int n = read(fd, readBuf, READ_SIZE-1);
296 s.append(readBuf, n);
306 if (s.length() > size_t(__INT_MAX__)) {
307 XmlRpcUtil::error(
"XmlRpcSocket::nbRead: text size (%u) exceeds the maximum allowed size (%s).",
308 s.length(), __INT_MAX__);
321 if (s.length() > size_t(__INT_MAX__)) {
322 XmlRpcUtil::error(
"XmlRpcSocket::nbWrite: text size (%u) exceeds the maximum allowed size(%s)",
323 s.length(), __INT_MAX__);
326 int nToWrite = int(s.length()) - *bytesSoFar;
327 char *sp =
const_cast<char*
>(s.c_str()) + *bytesSoFar;
328 bool wouldBlock =
false;
330 while ( nToWrite > 0 && ! wouldBlock ) {
331 #if defined(_WINDOWS) 332 int n = send(fd, sp, nToWrite, 0);
334 int n = write(fd, sp, nToWrite);
336 XmlRpcUtil::log(5,
"XmlRpcSocket::nbWrite: send/write returned %d.", n);
356 #if defined(_WINDOWS) 357 return WSAGetLastError();
377 strerror_s(err,60,error);
379 snprintf(err,
sizeof(err),
"%s",strerror(error));
381 return std::string(err);
387 socklen_t ss_len =
sizeof(ss);
388 getsockname(socket, (sockaddr *)&ss, &ss_len);
390 sockaddr_in *sin = (sockaddr_in *)&ss;
391 sockaddr_in6 *sin6 = (sockaddr_in6 *)&ss;
393 switch (ss.ss_family)
396 return ntohs(sin->sin_port);
398 return ntohs(sin6->sin6_port);
static bool setReuseAddr(int socket)
static int get_port(int socket)
static int accept(int socket)
Accept a client connection request.
static void error(const char *fmt,...)
Dump error messages somewhere.
static bool nbRead(int socket, std::string &s, bool *eof)
Read text from the specified socket. Returns false on error.
static bool connect(int socket, std::string &host, int port)
Connect a socket to a server (from a client)
static std::string getErrorMsg()
Returns message corresponding to last error.
static bool bind(int socket, int port)
Bind to a specified port.
static int getError()
Returns last errno.
static bool listen(int socket, int backlog)
Set socket in listen mode.
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
static void close(int socket)
Closes a socket.
static bool nbWrite(int socket, std::string &s, int *bytesSoFar)
Write text to the specified socket. Returns false on error.
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
static bool nonFatalError()
static void log(int level, const char *fmt,...)
Dump messages somewhere.