Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

client.cc

00001 #include <iostream>
00002 #include <string.h>
00003 #ifdef SOLARIS
00004 #include <strings.h>
00005 #include <stdio.h>
00006 #endif
00007 #include <sys/socket.h>
00008 #include <arpa/inet.h>
00009 #include <unistd.h>
00010 #include <errno.h>
00011 #include <sys/time.h>
00012 #include <fcntl.h>
00013 
00014 #include "client.h"
00015 
00016 #define DEBUG
00017 
00018 using namespace std;
00019 
00020 const char* SockClient::errTable[] = {
00021     "None",
00022     "Socket Client Error: Failed to create socket",
00023     "Socket Client Error: Failed to connect to server",
00024     "Socket Client Error: Host look-up failed",
00025     "Socket Client Error: Socket read failed",
00026     "Socket Client Error: select() failed",
00027     "Socket Client Error: Read timeout"
00028 
00029 };
00030 
00031 int SockClient::connect2Server(char* hostName, int port)
00032 {
00033     int status;
00034 
00035     sockFd = socket(AF_INET, SOCK_STREAM, 0);
00036     if (sockFd < 0) 
00037     {
00038 #ifdef DEBUG
00039         fprintf(stderr, "SockClient::connect2Server: Failed to create socket: \
00040             %s \n", strerror(errno));
00041 #endif
00042     return E_SOCKET_CREAT;
00043     }  
00044     bzero(&servAddr, sizeof(servAddr));
00045     servAddr.sin_family = AF_INET;
00046     servAddr.sin_port = htons(port);
00047 
00048     host = gethostbyname(hostName);
00049     if (host == NULL) 
00050     {       
00051 #ifdef DEBUG
00052 
00053 #endif
00054         return E_HOST_LOOKUP;
00055     }
00056     bcopy(host->h_addr, &servAddr.sin_addr, host->h_length);
00057     addrLen = sizeof(struct sockaddr);
00058     status = connect(sockFd, (struct sockaddr*)&servAddr, addrLen);
00059     if (status < 0)
00060     {
00061 #ifdef DEBUG
00062         fprintf(stderr, "SockClient::connect2Server: Failed to connect(): %s \n",
00063             strerror(errno));
00064 #endif
00065         return E_CONNECT;
00066     }
00067     
00068     return 0;
00069 }
00070 
00071 int SockClient::reconnect()
00072 {
00073     sockFd = socket(AF_INET, SOCK_STREAM, 0);
00074     if (sockFd < 0) 
00075     {
00076 #ifdef DEBUG
00077         fprintf(stderr, "SockClient::reconnect: Failed to create socket: \
00078             %s \n", strerror(errno));
00079 #endif
00080     close(sockFd);
00081     return E_SOCKET_CREAT;
00082     }
00083     
00084     int status = connect(sockFd, (struct sockaddr*)&servAddr, addrLen);
00085     if (status < 0)
00086     {
00087 #ifdef DEBUG
00088         fprintf(stderr, "SockClient::reconnect: Failed to connect(): %s \n",
00089             strerror(errno));
00090 #endif
00091     close(sockFd);
00092         return E_CONNECT;
00093     }
00094     
00095     return 0;    
00096 }
00097 
00098 void SockClient::disconnect()
00099 {
00100     close(sockFd);
00101 }
00102 
00103 void SockClient::disconnect(char* bytes, int len)
00104 {
00105     write(sockFd, bytes, len);
00106     close(sockFd);
00107 }
00108 
00109 int SockClient::readLine(char* buf, int maxBytes, struct timeval tout,
00110                  int stripNLcharFlag)
00111 {
00112     int res, nRead = 0;
00113     fd_set readFd;
00114     int status;
00115 
00116     FD_ZERO(&readFd);
00117     FD_SET(sockFd, &readFd);
00118 
00119     status = select(FD_SETSIZE, &readFd, NULL, NULL, &tout);
00120     if (status < 0)
00121     {
00122 #ifdef DEBUG
00123         perror("SockClient::readLine: select() failed: "); 
00124 #endif
00125     return E_SELECT;
00126     }
00127 
00128     if (FD_ISSET(sockFd, &readFd))
00129     {
00130         while (nRead < maxBytes)
00131         {
00132             res = read(sockFd, &buf[nRead], 1);
00133         if (res < 0)
00134         {
00135             if (errno == EINTR) continue;
00136 #ifdef DEBUG
00137             perror("SockClient::readLine: read() failed: ");
00138 #endif
00139             return E_RD;
00140         }
00141         if (res == 0)
00142         {
00143 #ifdef DEBUG
00144             fprintf(stderr, 
00145                     "SockClient::readLine: Server has closed connection, %d bytes read \n",
00146                         nRead);
00147 #endif
00148             break;
00149         }
00150         if (buf[nRead++] == '\n')
00151         {
00152                 if (stripNLcharFlag) buf[nRead] = 0;
00153         break;
00154         }
00155         }
00156         return nRead;
00157     }
00158     else
00159     return E_TIMEOUT;
00160 }
00161 
00162 int SockClient::readn(char* buf, int nBytes, int timeOut)
00163 {
00164     int status, n, nRead = 0;
00165 #ifdef SOLARIS    
00166     struct fd_set readFds;
00167 #else
00168     fd_set readFds;
00169 #endif    
00170     struct timeval tout;
00171     register int tleft;
00172 
00173     while (nRead < nBytes)
00174     {
00175     FD_ZERO(&readFds);
00176         FD_SET(sockFd, &readFds);
00177     tleft = ((nBytes - nRead) * timeOut)/nBytes;
00178         tout.tv_sec = tleft / 1000000;
00179         tout.tv_usec = tleft % 1000000;
00180     status = select(FD_SETSIZE, &readFds, NULL, NULL, &tout);
00181     if (status < 0)
00182         {
00183 #ifdef DEBUG
00184         perror("SockClient::readn: select() failed: ");
00185 #endif
00186             return E_SELECT;
00187     }
00188     if (FD_ISSET(sockFd, &readFds))
00189     {
00190             n = read(sockFd, &buf[nRead], nBytes - nRead);
00191         if (n < 0)
00192         {
00193 #ifdef DEBUG
00194         perror("SockClient::readn: read() failed: ");
00195 #endif
00196         return E_RD; // read error
00197         }
00198         if (n == 0) break;    // connection closed
00199         nRead += n;
00200     }
00201     else break; // timeout
00202     }   
00203     
00204     return nRead;
00205 }   
00206 
00207 int SockClient::writen(char* buf, int nBytes)
00208 {
00209     int nwrit = write(sockFd, buf, nBytes);
00210     if (nwrit < 0)
00211     {
00212 #ifdef DEBUG
00213         perror("SockClient::writen: write() failed: ");
00214 #endif
00215     return E_WRT;
00216     }
00217 
00218     return nwrit;
00219 }
00220 
00221 const char* SockClient::errMsg(int code)
00222 {
00223     if (code <= E_NONE && code > E_END)
00224         return errTable[-code];
00225     else
00226     return "Invalid Error Code";
00227 }

Generated on Mon Apr 30 13:32:33 2007 for Parkes M & C - PKMC C++ library API by  doxygen 1.4.4