Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

tcpsocket.cc

Go to the documentation of this file.
00001 //**************************************************************************
00002 // Parts of this code have been picked up from
00003 // http://libsocket.sourceforge.net/
00004 // written by Garrett Grice
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 // Force blocking send/recv
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 //**************************************************************************

Generated on Sun Jun 16 17:36:50 2002 for POSSE: Portable Object-oriented Scientific Steering Environment by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001