XmlRpc::XmlRpcSocket Class Reference

#include <XmlRpcSocket.h>

List of all members.


Detailed Description

A platform-independent socket API.

Static Public Member Functions

static int socket ()
 Creates a stream (TCP) socket. Returns -1 on failure.
static void close (int socket)
 Closes a socket.
static bool setNonBlocking (int socket)
 Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.
static bool nbRead (int socket, std::string &s, bool *eof, SSL *ssl)
 Read text from the specified socket. Returns false on error.
static bool nbWrite (int socket, std::string &s, int *bytesSoFar, SSL *ssl)
 Write text to the specified socket. Returns false on error.
static bool setReuseAddr (int socket)
 Allow the port the specified socket is bound to to be re-bound immediately so server re-starts are not delayed.
static bool bind (int socket, int port)
 Bind to a specified port.
static bool listen (int socket, int backlog)
 Set socket in listen mode.
static int accept (int socket)
 Accept a client connection request.
static bool connect (int socket, std::string &host, int port)
 Connect a socket to a server (from a client).
static int getPort (int socket)
 Get the port of a bound socket.
static bool nonFatalError ()
 Returns true if the last error was not a fatal one (eg, EWOULDBLOCK).
static int getError ()
 Returns last errno.
static std::string getErrorMsg ()
 Returns message corresponding to last error.
static std::string getErrorMsg (int error)
 Returns message corresponding to error.

Member Function Documentation

int XmlRpcSocket::socket (  )  [static]

Creates a stream (TCP) socket. Returns -1 on failure.

00070 {
00071   initWinSock();
00072   return (int) ::socket(AF_INET, SOCK_STREAM, 0);
00073 }

void XmlRpcSocket::close ( int  socket  )  [static]

Closes a socket.

00078 {
00079   XmlRpcUtil::log(4, "XmlRpcSocket::close: fd %d.", fd);
00080 #if defined(_WINDOWS)
00081   closesocket(fd);
00082 #else
00083   ::close(fd);
00084 #endif // _WINDOWS
00085 }

bool XmlRpcSocket::setNonBlocking ( int  socket  )  [static]

Sets a stream (TCP) socket to perform non-blocking IO. Returns false on failure.

00092 {
00093 #if defined(_WINDOWS)
00094   unsigned long flag = 1;
00095   return (ioctlsocket((SOCKET)fd, FIONBIO, &flag) == 0);
00096 #else
00097   return (fcntl(fd, F_SETFL, O_NONBLOCK) == 0);
00098 #endif // _WINDOWS
00099 }

bool XmlRpcSocket::nbRead ( int  socket,
std::string &  s,
bool *  eof,
SSL *  ssl 
) [static]

Read text from the specified socket. Returns false on error.

00169 {
00170   const int READ_SIZE = 4096;   // Number of bytes to attempt to read at a time
00171   char readBuf[READ_SIZE];
00172 
00173   bool wouldBlock = false;
00174   *eof = false;
00175 
00176   while ( ! wouldBlock && ! *eof) {
00177 #if defined(_WINDOWS)
00178     int n = recv(fd, readBuf, READ_SIZE-1, 0);
00179 #else
00180     int n = 0;
00181     if (ssl != (SSL *) NULL) {
00182 #ifdef USE_SSL
00183       n = SSL_read(ssl, readBuf, READ_SIZE-1);
00184 #endif      
00185     } else {
00186       n = read(fd, readBuf, READ_SIZE-1);
00187     }
00188 #endif
00189     XmlRpcUtil::log(5, "XmlRpcSocket::nbRead: read/recv returned %d.", n);
00190 
00191     if (n > 0) {
00192       readBuf[n] = 0;
00193       s.append(readBuf, n);
00194     } else if (n == 0) {
00195       *eof = true;
00196     } else if (nonFatalError()) {
00197       wouldBlock = true;
00198     } else {
00199       return false;   // Error
00200     }
00201   }
00202   return true;
00203 }

bool XmlRpcSocket::nbWrite ( int  socket,
std::string &  s,
int *  bytesSoFar,
SSL *  ssl 
) [static]

Write text to the specified socket. Returns false on error.

00209 {
00210   int nToWrite = int(s.length()) - *bytesSoFar;
00211   char *sp = const_cast<char*>(s.c_str()) + *bytesSoFar;
00212   bool wouldBlock = false;
00213 
00214   while ( nToWrite > 0 && ! wouldBlock ) {
00215 #if defined(_WINDOWS)
00216     int n = send(fd, sp, nToWrite, 0);
00217 #else
00218     int n = 0;
00219     if (ssl != (SSL *) NULL) {
00220 #ifdef USE_SSL
00221       n = SSL_write(ssl, sp, nToWrite);
00222 #endif      
00223     } else {
00224       n = write(fd, sp, nToWrite);
00225     }
00226 #endif
00227     XmlRpcUtil::log(5, "XmlRpcSocket::nbWrite: send/write returned %d.", n);
00228 
00229     if (n > 0) {
00230       sp += n;
00231       *bytesSoFar += n;
00232       nToWrite -= n;
00233     } else if (nonFatalError()) {
00234       wouldBlock = true;
00235     } else {
00236       return false;   // Error
00237     }
00238   }
00239   return true;
00240 }

bool XmlRpcSocket::setReuseAddr ( int  socket  )  [static]

Allow the port the specified socket is bound to to be re-bound immediately so server re-starts are not delayed.

Returns false on failure.

00104 {
00105   // Allow this port to be re-bound immediately so server re-starts are not delayed
00106   int sflag = 1;
00107   return (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&sflag, sizeof(sflag)) == 0);
00108 }

bool XmlRpcSocket::bind ( int  socket,
int  port 
) [static]

Bind to a specified port.

00114 {
00115   struct sockaddr_in saddr;
00116   memset(&saddr, 0, sizeof(saddr));
00117   saddr.sin_family = AF_INET;
00118   saddr.sin_addr.s_addr = htonl(INADDR_ANY);
00119   saddr.sin_port = htons((u_short) port);
00120   return (::bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) == 0);
00121 }

bool XmlRpcSocket::listen ( int  socket,
int  backlog 
) [static]

Set socket in listen mode.

00127 {
00128   return (::listen(fd, backlog) == 0);
00129 }

int XmlRpcSocket::accept ( int  socket  )  [static]

Accept a client connection request.

00134 {
00135   struct sockaddr_in addr;
00136   socklen_t addrlen = sizeof(addr);
00137 
00138   return (int) ::accept(fd, (struct sockaddr*)&addr, &addrlen);
00139 }

bool XmlRpcSocket::connect ( int  socket,
std::string &  host,
int  port 
) [static]

Connect a socket to a server (from a client).

00146 {
00147   struct sockaddr_in saddr;
00148   memset(&saddr, 0, sizeof(saddr));
00149   saddr.sin_family = AF_INET;
00150 
00151   struct hostent *hp = gethostbyname(host.c_str());
00152   if (hp == 0) return false;
00153 
00154   saddr.sin_family = hp->h_addrtype;
00155   memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
00156   saddr.sin_port = htons((u_short) port);
00157 
00158   // For asynch operation, this will return EWOULDBLOCK (windows) or
00159   // EINPROGRESS (linux) and we just need to wait for the socket to be writable...
00160   int result = ::connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));
00161   return result == 0 || nonFatalError();
00162 }

int XmlRpcSocket::getPort ( int  socket  )  [static]

Get the port of a bound socket.

00245 {
00246   struct sockaddr_in saddr;
00247   socklen_t saddr_len = sizeof(saddr);
00248   int port;
00249 
00250   int result = ::getsockname(socket, (sockaddr*) &saddr, &saddr_len);
00251 
00252   if (result != 0) {
00253     port = -1;
00254   } else {
00255     port = ntohs(saddr.sin_port);
00256   }
00257   return port;
00258 }

bool XmlRpcSocket::nonFatalError (  )  [static]

Returns true if the last error was not a fatal one (eg, EWOULDBLOCK).

00062 {
00063   int err = XmlRpcSocket::getError();
00064   return (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK || err == EINTR);
00065 }

int XmlRpcSocket::getError (  )  [static]

Returns last errno.

00264 {
00265 #if defined(_WINDOWS)
00266   return WSAGetLastError();
00267 #else
00268   return errno;
00269 #endif
00270 }

std::string XmlRpcSocket::getErrorMsg (  )  [static]

Returns message corresponding to last error.

00276 {
00277   return getErrorMsg(getError());
00278 }

std::string XmlRpcSocket::getErrorMsg ( int  error  )  [static]

Returns message corresponding to error.

00283 {
00284   char err[60];
00285   snprintf(err,sizeof(err),"error %d", error);
00286   return std::string(err);
00287 }


The documentation for this class was generated from the following files:
Generated on Thu Apr 17 13:19:31 2008 for ITM OverSim by  doxygen 1.5.3