00001
00002 #include <sys/types.h>
00003 #include <sys/socket.h>
00004 #include <netinet/in.h>
00005 #include <arpa/inet.h>
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <unistd.h>
00010 #include <errno.h>
00011
00012
00013 #define SA struct sockaddr *
00014
00015 #define MSG_EOF MSG_FIN
00016
00017 const size_t MAXLINE = 2048;
00018
00019
00020
00021 #include <fstream>
00022 #include <iostream>
00023 #include <iomanip>
00024 #include <string>
00025 #include <vector>
00026
00027 using namespace std;
00028
00029
00030
00031
00032
00033 class ocSocket
00034 {
00035
00036
00037
00038
00039 vector <char> readBuff;
00040 string error;
00041
00042
00043 struct sockaddr_in serv;
00044 int sockfd;
00045
00046
00047 ssize_t amountRead;
00048
00049 protected:
00050
00051
00052 void fatal_err( const char * errIn )
00053 {
00054 error = "\r\nFatal Error: ";
00055 error += errIn;
00056 throw exception();
00057 }
00058 void non_fatal_error( const char * errIn )
00059 {
00060 error = "\r\nError: ";
00061 error += errIn;
00062 }
00063
00064 public:
00065
00066
00067
00068
00069
00070
00071 ocSocket( const char * address, int port ):readBuff(MAXLINE),error("")
00072 {
00073 if( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00074 {
00075 fatal_err("socket function error");
00076 }
00077 memset(&serv, 0, sizeof(serv));
00078 serv.sin_family = AF_INET;
00079 if( inet_aton(address, &serv.sin_addr) != 1 )
00080 {
00081 fatal_err("bad address string");
00082 }
00083 serv.sin_port = htons( port );
00084
00085 if (connect(sockfd, (SA) &serv, sizeof(serv)) < 0)
00086 {
00087 fatal_err("connect function error");
00088 }
00089 }
00090 virtual ~ocSocket()
00091 {
00092 close(sockfd);
00093 }
00094
00095
00096
00097 bool SetTimeoutTime( size_t seconds, size_t useconds = 0 )
00098 {
00099 struct timeval tv;
00100 tv.tv_sec = seconds;
00101 tv.tv_usec = useconds;
00102 return (setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv) ) == 0);
00103 }
00104
00105
00106
00107
00108 ssize_t Write( const char * in, size_t amount )
00109 {
00110 size_t nwrote;
00111 const char *ptr;
00112 ptr = in;
00113 nwrote = 0;
00114
00115 while( (amount-nwrote) > 0)
00116 {
00117 nwrote = write(sockfd, ptr, amount - nwrote);
00118 if( nwrote <= 0 )
00119 {
00120 if (errno == EINTR) nwrote = 0;
00121 else fatal_err("could not write everything to socket");
00122 }
00123 ptr += nwrote;
00124 }
00125 return(amount);
00126 }
00127
00128
00129
00130
00131 char * Read( size_t amount )
00132 {
00133 amountRead = 0;
00134
00135
00136
00137 if( readBuff.size() < amount+1 )
00138 {
00139 readBuff.resize(amount+1);
00140 }
00141 char * base = & readBuff[0];
00142 do
00143 {
00144 amountRead += read( sockfd, base, amount-amountRead );
00145 if( amountRead > 0 ) base = & readBuff[amountRead];
00146
00147
00148
00149 } while( amountRead < (ssize_t)amount && errno == EINTR );
00150
00151
00152
00153
00154 if( amountRead == -1 && errno == EWOULDBLOCK)
00155 {
00156 non_fatal_error( "socket timeout on read" );
00157 return NULL;
00158 }
00159 return & readBuff[0];
00160 }
00161
00162
00163
00164
00165 char * ReadLine( size_t amount = 4096L )
00166 {
00167 amountRead = 0;
00168
00169
00170 if( readBuff.size() < (size_t)(amount+1) )
00171 {
00172 readBuff.resize(amount+1);
00173 }
00174
00175 char * base = & readBuff[0];
00176 do
00177 {
00178
00179 ssize_t nRead = recv( sockfd, base, amount-amountRead, MSG_PEEK );
00180 if( nRead > 0 )
00181 {
00182 base[nRead] = '\0';
00183 string temp = base;
00184
00185 string::size_type idx;
00186 idx = temp.find( "\n" );
00187
00188 if(idx != string::npos )
00189 {
00190 amountRead += read( sockfd, base, idx+1 );
00191 break;
00192 }
00193 else
00194 {
00195 amountRead += read( sockfd, base, nRead );
00196 }
00197
00198 if( amountRead > 0 )
00199 {
00200 base = & readBuff[amountRead];
00201 }
00202 }
00203 else
00204 {
00205
00206 amountRead = nRead;
00207 }
00208
00209 }
00210 while( amountRead < (ssize_t) amount && errno == EINTR );
00211
00212 if( amountRead )
00213 {
00214 readBuff[amountRead] = '\0';
00215 }
00216
00217
00218 if( amountRead == -1 && errno == EWOULDBLOCK)
00219 {
00220 non_fatal_error( "socket timeout on read" );
00221 return NULL;
00222 }
00223 return & readBuff[0];
00224 }
00225
00226
00227
00228
00229 ssize_t GetAmountRead( void )
00230 {
00231 return amountRead;
00232 }
00233
00234
00235
00236
00237 string & getError(void)
00238 {
00239 return error;
00240 }
00241 };