00001
00002
00003
00004
00005
00006 #include <string.h>
00007 #include <strings.h>
00008 #include <sys/socket.h>
00009 #include <netdb.h>
00010 #include <netinet/in.h>
00011 #include <unistd.h>
00012 #include <fcntl.h>
00013 #include <errno.h>
00014 #include <iostream.h>
00015 #include <stdio.h>
00016 #include "tcpsocket.h"
00017 #include "errcode.h"
00018 #include "misc.h"
00019
00020 #if defined (HPUX) || defined (__CYGWIN32__)
00021 #define RECV_FLAG 0
00022 #define socklen_t int
00023 #else
00024 #define RECV_FLAG MSG_WAITALL
00025 #endif
00026
00027 int BlockSocket(int sockid);
00028 int recv_all(int s, unsigned char *buf, int len, unsigned int flags);
00029 int send_all(int s, unsigned char *buf, int len, unsigned int flags);
00030 static double bytes_sent = 0.0, bytes_recd = 0.0;
00031 static int time_to_send = 0, time_to_recv = 0;
00032
00033 TCPSocket::TCPSocket()
00034 {
00035 recvfd = 0;
00036 sockfd = 0;
00037 }
00038
00039 TCPSocket::~TCPSocket()
00040 {
00041 }
00042
00043 bool TCPSocket::Create()
00044 {
00045 sockfd = socket(AF_INET, SOCK_STREAM, 0);
00046 if (sockfd == -1)
00047 return false;
00048
00049 BlockSocket(sockfd);
00050 return true;
00051 }
00052
00053 bool TCPSocket::Bind(int port)
00054 {
00055 Create();
00056
00057 INetAddress.sin_family = AF_INET;
00058 INetAddress.sin_port = htons(port);
00059 INetAddress.sin_addr.s_addr = INADDR_ANY;
00060 bzero((char *) &(INetAddress.sin_zero), 8);
00061
00062 if (bind(sockfd, (struct sockaddr *) &INetAddress, sizeof(struct sockaddr)) == -1)
00063 {
00064 perror("TCPSocket::Bind");
00065 return false;
00066 }
00067
00068 return true;
00069 }
00070
00071 bool TCPSocket::Connect(char *server, int port)
00072 {
00073 hostent *Host;
00074
00075 Create();
00076
00077 if ((Host = gethostbyname(server)) == NULL)
00078 {
00079 #ifndef HPUX
00080 perror("gethostbyname");
00081 #endif
00082 return false;
00083 }
00084
00085 INetAddress.sin_family = AF_INET;
00086 INetAddress.sin_port = htons(port);
00087 INetAddress.sin_addr = *((struct in_addr *) Host->h_addr);
00088 bzero((char *) &(INetAddress.sin_zero), 8);
00089
00090 if (connect(sockfd, (struct sockaddr *) &INetAddress, sizeof(struct sockaddr)) == -1)
00091 {
00092 perror("TCPSocket::Connect");
00093 return false;
00094 }
00095
00096 return true;
00097 }
00098
00099 int TCPSocket::SendBytes(int size, const void *data)
00100 {
00101 int sockid = recvfd ? recvfd : sockfd;
00102 int nsent = send_all(sockid, (unsigned char*) data, size, 0);
00103
00104 if (nsent != size)
00105 {
00106 cout << "TCPSocket::Send: Error sending data!";
00107 if (nsent >= 0)
00108 cout << " (only " << nsent << " of " << size << " bytes sent)" << endl;
00109 cout << " Bad connection....throwing exception!" << endl << flush;
00110 int err = ERR_SEND_MESG;
00111 throw err;
00112 }
00113
00114 return nsent;
00115 }
00116
00117 int TCPSocket::RecvBytes(int size, void *data)
00118 {
00119 int sockid = recvfd ? recvfd : sockfd;
00120 int nrecv = recv_all(sockid, (unsigned char *) data, size, RECV_FLAG);
00121
00122 if (nrecv != size)
00123 {
00124 cout << "TCPSocket::Recv: Error receiving data!";
00125 if (nrecv >= 0)
00126 cout << " (only " << nrecv << " of " << size << " bytes received)" << endl;
00127 cout << " Bad connection....throwing exception!" << endl << flush;
00128 int err = ERR_RECV_MESG;
00129 throw err;
00130 }
00131
00132 return nrecv;
00133 }
00134
00135 bool TCPSocket::Close()
00136 {
00137 return (close(recvfd ? recvfd : sockfd) != -1);
00138 }
00139
00140 bool TCPSocket::InboundClose()
00141 {
00142 return (close(recvfd) != -1);
00143 }
00144
00145 bool TCPSocket::Listen()
00146 {
00147 if (listen(sockfd, 5) == -1)
00148 {
00149 perror("TCPSocket::Listen");
00150 return false;
00151 }
00152
00153 return true;
00154 }
00155
00156 bool TCPSocket::Accept()
00157 {
00158 socklen_t sin_size = sizeof(struct sockaddr_in);
00159 sockaddr_in RemoteAddress;
00160 int maxtries = 10;
00161 int num_tries = 0;
00162
00163 while (((recvfd = accept(sockfd, (struct sockaddr *) &RemoteAddress, &sin_size)) == -1) && num_tries < maxtries)
00164 {
00165 usleep(100000);
00166 ++num_tries;
00167 }
00168 if (num_tries == maxtries)
00169 {
00170 perror("accept");
00171 return false;
00172 }
00173 BlockSocket(recvfd);
00174
00175 return true;
00176 }
00177
00178 char *TCPSocket::PeerName()
00179 {
00180 int sockid = recvfd ? recvfd : sockfd;
00181 static char *str = new char[100];
00182 struct sockaddr_in name;
00183 struct hostent *ent;
00184 socklen_t len = sizeof(name);
00185
00186 getpeername(sockid, (struct sockaddr *) &name, &len);
00187 ent = gethostbyaddr((const char *) &name.sin_addr.s_addr, sizeof(struct in_addr), AF_INET);
00188 int size = strlen(ent->h_name);
00189 memcpy(str, ent->h_name, size);
00190 str[size] = '\0';
00191
00192 return str;
00193 }
00194
00195 int TCPSocket::PeerPort()
00196 {
00197 int sockid = recvfd ? recvfd : sockfd;
00198 struct sockaddr_in name;
00199 socklen_t len = sizeof(name);
00200
00201 getpeername(sockid, (struct sockaddr *) &name, &len);
00202
00203 return name.sin_port;
00204 }
00205
00206 char *TCPSocket::SocketName()
00207 {
00208 int sockid = recvfd ? recvfd : sockfd;
00209 static char *str = new char[200];
00210 struct sockaddr_in name;
00211 socklen_t len = sizeof(name);
00212 struct hostent *ent;
00213
00214 getsockname(sockid, (struct sockaddr *) &name, &len);
00215 ent = gethostbyaddr((const char *) &name.sin_addr.s_addr, sizeof(struct in_addr), AF_INET);
00216 int size = strlen(ent->h_name);
00217 memcpy(str, ent->h_name, size);
00218 str[size] = '\0';
00219
00220 return str;
00221 }
00222
00223 int TCPSocket::SocketPort()
00224 {
00225 int sockid = recvfd ? recvfd : sockfd;
00226 struct sockaddr_in name;
00227 socklen_t len = sizeof(name);
00228
00229 getsockname(sockid, (struct sockaddr *) &name, &len);
00230
00231 return name.sin_port;
00232 }
00233
00234
00235 int BlockSocket(int sockid)
00236 {
00237 int fflags = fcntl(sockid, F_GETFL);
00238
00239 fflags &= ~O_NONBLOCK;
00240 fcntl(sockid, F_SETFL, fflags);
00241
00242 return 0;
00243 }
00244
00245 double TCPSocket::BytesSent()
00246 {
00247 return bytes_sent;
00248 }
00249
00250 double TCPSocket::BytesRecd()
00251 {
00252 return bytes_recd;
00253 }
00254
00255 int TCPSocket::SendTime()
00256 {
00257 return (time_to_send ? time_to_send : 1);
00258 }
00259
00260 int TCPSocket::RecvTime()
00261 {
00262 return (time_to_recv ? time_to_recv : 1);
00263 }
00264
00265 TCPSocket &TCPSocket::operator = (const TCPSocket & T)
00266 {
00267 if (this == &T)
00268 return *this;
00269
00270 sockfd = T.sockfd;
00271 recvfd = T.recvfd;
00272 memcpy(&INetAddress, &(T.INetAddress), sizeof(T.INetAddress));
00273 memcpy(&RemoteAddress, &(T.RemoteAddress), sizeof(T.RemoteAddress));
00274
00275 return *this;
00276 }
00277
00278 int recv_all(int s, unsigned char *buf, int len, unsigned int flags)
00279 {
00280 int count;
00281 int total = 0;
00282 int tstart = myTimer();
00283
00284 while (len > 0)
00285 {
00286 count = recv(s, buf, len, flags);
00287 if (count == -1 && errno == EINTR)
00288 continue;
00289 if (count <= 0)
00290 return -1;
00291 buf += count;
00292 len -= count;
00293 total += count;
00294 }
00295
00296 time_to_recv += myTimer()-tstart;
00297 bytes_recd += (double) total;
00298 return total;
00299 }
00300
00301 int send_all(int s, unsigned char *buf, int len, unsigned int flags)
00302 {
00303 int count;
00304 int total = 0;
00305 int tstart = myTimer();
00306
00307 while (len > 0)
00308 {
00309 count = send(s, buf, len, flags);
00310 if (count == -1 && errno == EINTR)
00311 continue;
00312 if (count <= 0)
00313 return -1;
00314 buf += count;
00315 len -= count;
00316 total += count;
00317 }
00318
00319 time_to_send += myTimer()-tstart;
00320 bytes_sent += (double) total;
00321 return total;
00322 }
00323