#include <XmlRpcSocket.h>
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. |
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] |
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] |
std::string XmlRpcSocket::getErrorMsg | ( | ) | [static] |
std::string XmlRpcSocket::getErrorMsg | ( | int | error | ) | [static] |