7# if defined( _WINDOWS )
12# define EINPROGRESS WSAEINPROGRESS
13# define EWOULDBLOCK WSAEWOULDBLOCK
14# define ETIMEDOUT WSAETIMEDOUT
21# include <netinet/in.h>
23# include <sys/socket.h>
24# include <sys/types.h>
33#if defined( _WINDOWS )
36 static bool wsInit =
false;
39 WORD wVersionRequested = MAKEWORD( 2, 0 );
41 WSAStartup( wVersionRequested, &wsaData );
53static inline bool nonFatalError() {
55 return ( err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK || err == EINTR );
60 return (
int)
::socket( AF_INET, SOCK_STREAM, 0 );
65#if defined( _WINDOWS )
73#if defined( _WINDOWS )
74 unsigned long flag = 1;
75 return ( ioctlsocket( (SOCKET)fd, FIONBIO, &
flag ) == 0 );
77 return ( fcntl( fd, F_SETFL, O_NONBLOCK ) == 0 );
84 return ( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (
const char*)&sflag,
sizeof( sflag ) ) ==
90 struct sockaddr_in saddr;
91 memset( &saddr, 0,
sizeof( saddr ) );
92 saddr.sin_family = AF_INET;
93 saddr.sin_addr.s_addr = htonl( INADDR_ANY );
94 saddr.sin_port = htons( (u_short)port );
95 return (
::bind( fd, (
struct sockaddr*)&saddr,
sizeof( saddr ) ) == 0 );
102 struct sockaddr_in addr;
103#if defined( _WINDOWS )
108 addrlen =
sizeof( addr );
110 return (
int)
::accept( fd, (
struct sockaddr*)&addr, &addrlen );
115 struct sockaddr_in saddr;
116 memset( &saddr, 0,
sizeof( saddr ) );
117 saddr.sin_family = AF_INET;
119 struct hostent* hp = gethostbyname( host.c_str() );
120 if ( hp == 0 )
return false;
122 saddr.sin_family = hp->h_addrtype;
123 memcpy( &saddr.sin_addr, hp->h_addr, hp->h_length );
124 saddr.sin_port = htons( (u_short)port );
128 int result =
::connect( fd, (
struct sockaddr*)&saddr,
sizeof( saddr ) );
129 return result == 0 || nonFatalError();
134 const int READ_SIZE = 4096;
135 char readBuf[READ_SIZE];
137 bool wouldBlock =
false;
140 while ( !wouldBlock && !*eof )
142#if defined( _WINDOWS )
143 int n = recv( fd, readBuf, READ_SIZE - 1, 0 );
145 int n = read( fd, readBuf, READ_SIZE - 1 );
152 s.append( readBuf,
n );
154 else if (
n == 0 ) { *eof =
true; }
155 else if ( nonFatalError() ) { wouldBlock =
true; }
166 int nToWrite = int(
s.length() ) - *bytesSoFar;
167 char* sp =
const_cast<char*
>(
s.c_str() ) + *bytesSoFar;
168 bool wouldBlock =
false;
170 while ( nToWrite > 0 && !wouldBlock )
172#if defined( _WINDOWS )
173 int n = send( fd, sp, nToWrite, 0 );
175 int n = write( fd, sp, nToWrite );
185 else if ( nonFatalError() ) { wouldBlock =
true; }
196#if defined( _WINDOWS )
197 return WSAGetLastError();
209 snprintf( err,
sizeof( err ),
"error %d", error );
210 return std::string( err );
static int socket()
Creates a stream (TCP) socket. Returns -1 on failure.
static bool listen(int socket, int backlog)
Set socket in listen mode.
static int getError()
Returns last errno.
static int accept(int socket)
Accept a client connection request.
static bool nbWrite(int socket, std::string &s, int *bytesSoFar)
Write text to the specified socket. Returns false on error.
static bool setReuseAddr(int socket)
static bool connect(int socket, std::string &host, int port)
Connect a socket to a server (from a client).
static bool setNonBlocking(int socket)
Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
static void close(int socket)
Closes a socket.
static bool nbRead(int socket, std::string &s, bool *eof)
Read text from the specified socket. Returns false on error.
static bool bind(int socket, int port)
Bind to a specified port.
static std::string getErrorMsg()
Returns message corresponding to last error.
static void log(int level, const char *fmt,...)
Dump messages somewhere.