12# define EINPROGRESS WSAEINPROGRESS
13# define EWOULDBLOCK WSAEWOULDBLOCK
14# define ETIMEDOUT WSAETIMEDOUT
19# include <sys/types.h>
20# include <sys/socket.h>
21# include <netinet/in.h>
40 static bool wsInit =
false;
43 WORD wVersionRequested = MAKEWORD( 2, 0 );
45 WSAStartup(wVersionRequested, &wsaData);
62 return (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK || err == EINTR);
71 return (
int)
::socket(AF_INET, SOCK_STREAM, 0);
93 unsigned long flag = 1;
94 return (ioctlsocket((SOCKET)fd, FIONBIO, &flag) == 0);
96 return (fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
106 return (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (
const char *)&sflag,
sizeof(sflag)) == 0);
114 struct sockaddr_in saddr;
115 memset(&saddr, 0,
sizeof(saddr));
116 saddr.sin_family = AF_INET;
117 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
118 saddr.sin_port = htons((u_short) port);
119 return (
::bind(fd, (
struct sockaddr *)&saddr,
sizeof(saddr)) == 0);
127 return (
::listen(fd, backlog) == 0);
134 struct sockaddr_in addr;
140 addrlen =
sizeof(addr);
142 return (
int)
::accept(fd, (
struct sockaddr*)&addr, &addrlen);
151 struct sockaddr_in saddr;
152 memset(&saddr, 0,
sizeof(saddr));
153 saddr.sin_family = AF_INET;
155 struct hostent *hp = gethostbyname(host.c_str());
156 if (hp == 0)
return false;
158 saddr.sin_family = hp->h_addrtype;
159 memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
160 saddr.sin_port = htons((u_short) port);
164 int result =
::connect(fd, (
struct sockaddr *)&saddr,
sizeof(saddr));
165 return result == 0 || nonFatalError();
174 const int READ_SIZE = 4096;
175 char readBuf[READ_SIZE];
177 bool wouldBlock =
false;
180 while ( ! wouldBlock && ! *eof) {
182 int n = recv(fd, readBuf, READ_SIZE-1, 0);
184 int n = read(fd, readBuf, READ_SIZE-1);
190 s.append(readBuf,
n);
193 }
else if (nonFatalError()) {
207 int nToWrite = int(
s.length()) - *bytesSoFar;
208 char *sp =
const_cast<char*
>(
s.c_str()) + *bytesSoFar;
209 bool wouldBlock =
false;
211 while ( nToWrite > 0 && ! wouldBlock ) {
213 int n = send(fd, sp, nToWrite, 0);
215 int n = write(fd, sp, nToWrite);
223 }
else if (nonFatalError()) {
238 return WSAGetLastError();
257 snprintf(err,
sizeof(err),
"error %d", error);
258 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.