Socket.cpp
Go to the documentation of this file.
00001 
00009 // Implementation of the Socket class.
00010 
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <sys/time.h>
00014 #include <sys/types.h>
00015 
00016 #include "canon_vbc50i/libSock/Socket.h"
00017 #include <string.h>
00018 #include <errno.h>
00019 #include <fcntl.h>
00020 
00021 #ifdef MACOSX
00022 #define socklen_t int
00023 #define MSG_NOSIGNAL 0
00024 #endif
00025 
00026 
00027 Socket::Socket() : m_sock ( -1 )
00028 {
00029 
00030         outputErrors = true;
00031         broken_pipe = false;
00032         accepting = false;
00033         memset ( &m_addr, 0, sizeof ( m_addr ) );
00034 
00035         server = false;
00036         host = NULL;
00037         port = 0;
00038 
00039 }
00040 
00041 
00042 Socket::Socket(const char * _host, int _port) : m_sock(-1)
00043 {
00044         outputErrors = true;
00045         broken_pipe = false;
00046         accepting = false;
00047         memset ( &m_addr, 0, sizeof ( m_addr ) );
00048 
00049         server = false;
00050         host = strdup(_host);
00051         port = _port;
00052 }
00053         
00054 Socket::Socket(int _port) : m_sock(-1)
00055 {
00056         outputErrors = true;
00057         broken_pipe = false;
00058         accepting = false;
00059         memset ( &m_addr, 0, sizeof ( m_addr ) );
00060 
00061         server = true;
00062         host = NULL;
00063         port = _port;
00064 }
00065         
00066 
00067 Socket::~Socket()
00068 {
00069         if ( IsOpen() ) 
00070         {
00071                 Close();
00072         }
00073 
00074         if (host != NULL) {
00075                 free(host);
00076                 host = NULL;
00077         }
00078 }
00079 
00080 bool Socket::Close()
00081 {
00082         shutdown(m_sock,2);
00083         close(m_sock);
00084         broken_pipe = false;
00085         return true;
00086 }
00087 
00088 bool Socket::Create()
00089 {
00090         broken_pipe = false;
00091         m_sock = socket ( AF_INET, SOCK_STREAM, 0 );
00092 
00093         if ( ! IsOpen() )
00094                 return false;
00095 
00096 
00097         // TIME_WAIT - argh
00098         int on = 1;
00099         if ( setsockopt ( m_sock, SOL_SOCKET, 
00100                                 SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
00101         {
00102                 if (outputErrors) perror("Create");
00103                 return false;
00104         }
00105         if ( setsockopt ( m_sock, SOL_SOCKET, 
00106                                 SO_KEEPALIVE, ( const char* ) &on, sizeof ( on ) ) == -1 )
00107         {
00108                 if (outputErrors) perror("Create");
00109                 return false;
00110         }
00111 
00112         return true;
00113 
00114 }
00115 
00116 
00117 
00118 bool Socket::Bind ( const int port )
00119 {
00120         broken_pipe = false;
00121 
00122         if ( ! IsOpen() )
00123         {
00124                 return false;
00125         }
00126 
00127 
00128 
00129         m_addr.sin_family = AF_INET;
00130         m_addr.sin_addr.s_addr = INADDR_ANY;
00131         m_addr.sin_port = htons ( port );
00132 
00133         int bind_return = bind ( m_sock,
00134                         ( struct sockaddr * ) &m_addr,
00135                         sizeof ( m_addr ) );
00136         if (bind_return == -1)
00137         {
00138                 if (outputErrors) perror("Bind");
00139                 return false;
00140         }
00141         return true;
00142 }
00143 
00144 
00145 bool Socket::Listen() 
00146 {
00147         broken_pipe = false;
00148         accepting = false;
00149         if ( ! IsOpen() )
00150         {
00151                 return false;
00152         }
00153 
00154         int listen_return = listen ( m_sock, MAXCONNECTIONS );
00155 
00156 
00157         accepting = ( listen_return != -1 );
00158         return accepting;
00159 }
00160 
00161 
00162 bool Socket::Accept ( Socket* new_socket ) const
00163 {
00164         int addr_length = sizeof ( m_addr );
00165         new_socket->m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
00166 
00167         return ( new_socket->m_sock > 0 );
00168 }
00169 
00170 
00171 size_t Socket::Send ( const unsigned char * s, size_t size) 
00172 {
00173         int status = send ( m_sock, s, size, MSG_NOSIGNAL );
00174         if ( status < 0 )
00175         {
00176                 switch (errno) {
00177                         case ECONNRESET:
00178                         case ENOTCONN:
00179                         case EPIPE:
00180                                 broken_pipe = true;
00181                                 break;
00182                         default :
00183                                 break;
00184                 }
00185                 if (outputErrors) {
00186                         char tmp[128];
00187                         sprintf(tmp,"Send %s:%d",host,port);
00188                         perror(tmp);
00189                 }
00190                 return 0;
00191         }
00192         else
00193         {
00194                 return (size_t)status;
00195         }
00196 }
00197 
00198 
00199 size_t Socket::Receive ( unsigned char * s, size_t max_size ) 
00200 {
00201         int status = recv ( m_sock, s, max_size , 0 );
00202 
00203         if ( status < 0 )
00204         {
00205                 //printf("status == -1   errno == %d in Socket::recv\n",errno);
00206                 switch (errno) {
00207                         case ECONNRESET:
00208                         case ENOTCONN:
00209                         case EPIPE:
00210                                 broken_pipe = true;
00211                                 break;
00212                         default :
00213                                 break;
00214                 }
00215                 if (outputErrors)  {
00216                         char tmp[128];
00217                         sprintf(tmp,"Receive %s:%d",host,port);
00218                         perror(tmp);
00219                 }
00220                 return 0;
00221         }
00222         else 
00223         {
00224                 return (size_t)status;
00225         }
00226 }
00227 
00228 
00229 bool Socket::Connect ( const char * host, const int port )
00230 {
00231         broken_pipe = false;
00232         if ( ! IsOpen() ) return false;
00233 
00234         m_addr.sin_family = AF_INET;
00235         m_addr.sin_port = htons ( port );
00236 
00237         int status = inet_pton ( AF_INET, host, &m_addr.sin_addr );
00238         if ( errno == EAFNOSUPPORT ) return false;
00239         if (status <= 0)
00240         {
00241                 struct hostent *_host_;
00242                 _host_ =  gethostbyname(host);
00243                 if (_host_ == NULL) return false;
00244                 memcpy(&m_addr.sin_addr.s_addr, _host_->h_addr, _host_->h_length);
00245         }
00246 
00247 
00248         status = connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
00249         if (status < 0)
00250         {
00251                 if (outputErrors) perror("Connect");
00252                 return false;
00253         }
00254 
00255         int opts = fcntl ( m_sock, F_GETFL );
00256         if (opts >= 0)
00257                 fcntl(m_sock,F_SETFL,opts | O_SYNC);
00258         return ( status == 0 );
00259 }
00260 
00261 void Socket::SetNonBlocking ( const bool b )
00262 {
00263 
00264         int opts;
00265 
00266         opts = fcntl ( m_sock, F_GETFL );
00267 
00268         if ( opts < 0 )
00269         {
00270                 return;
00271         }
00272 
00273         if ( b )
00274                 opts = ( opts | O_NONBLOCK );
00275         else
00276                 opts = ( opts & ~O_NONBLOCK );
00277 
00278         fcntl ( m_sock, F_SETFL,opts );
00279 
00280 }
00281 
00282 
00283 bool Socket::WaitData(size_t millisec)
00284 {
00285         struct timeval to = {0,0};
00286         to.tv_sec = (millisec/1000);
00287         to.tv_usec = (millisec%1000) * 1000;
00288         FD_ZERO(&rfs);FD_SET(m_sock,&rfs);
00289         int r = select(m_sock+1,&rfs,NULL,NULL,&to);
00290         if (r < 0) {
00291                 switch (errno) {
00292                         case EBADF:
00293                                 broken_pipe = true;
00294                                 break;
00295                         default :
00296                                 break;
00297                 }
00298                 if (outputErrors) {
00299                         char tmp[128];
00300                         sprintf(tmp,"Select %s:%d",host,port);
00301                         perror(tmp);
00302                 }
00303         }
00304         return (r >= 1);
00305 }
00306                 
00307 bool Socket::WaitBuffer(unsigned char * s, size_t size,
00308                 size_t millisec) 
00309 {
00310         unsigned int readbytes;
00311         double t1ms,t2ms,dtms,maxms;
00312         struct timeval tv1,tv2;
00313         struct timeval to = {0,0};
00314         maxms = millisec*1e-3;
00315         to.tv_sec = (millisec/1000);
00316         to.tv_usec = (millisec%1000) * 1000;
00317         gettimeofday(&tv1,NULL);
00318         readbytes = 0;
00319         t1ms = tv1.tv_sec+tv1.tv_usec*1e-6;
00320         while ((readbytes < size) && !broken_pipe)
00321         {
00322                 FD_ZERO(&rfs);FD_SET(m_sock,&rfs);
00323                 int r = select(m_sock+1,&rfs,NULL,NULL,&to);
00324                 if (r < 1) {
00325                         switch (errno) {
00326                                 case EBADF:
00327                                         broken_pipe = true;
00328                                         break;
00329                                 default :
00330                                         break;
00331                         }
00332                         if (outputErrors) {
00333                                 char tmp[128];
00334                                 sprintf(tmp,"Select %s:%d",host,port);
00335                                 perror(tmp);
00336                         }
00337                         return false;
00338                 }
00339                 //r = recv ( m_sock, s+readbytes, size-readbytes , 0 );
00340                 r = Receive ( s+readbytes, size-readbytes );
00341                 if (r>0) readbytes += r;
00342                 //printf("Rec %d\n",readbytes);
00343 
00344                 gettimeofday(&tv2,NULL);
00345                 t2ms = tv2.tv_sec+tv2.tv_usec*1e-6;
00346                 dtms = t2ms - t1ms;
00347                 if (dtms >= maxms) break;
00348                 dtms = maxms - dtms;
00349                 to.tv_sec = (unsigned int)(dtms);
00350                 to.tv_usec = (unsigned int)((dtms - to.tv_sec)*1e6);
00351         }
00352         return (readbytes == size);
00353 }
00354 
00355 bool Socket::SendAll(const unsigned char * s, size_t size,
00356                 size_t millisec) 
00357 {
00358         unsigned int sentbytes;
00359         double t1ms,t2ms,dtms,maxms;
00360         struct timeval tv1,tv2;
00361         gettimeofday(&tv1,NULL);
00362         maxms = millisec * 1e-3;
00363         t1ms = tv1.tv_sec+(tv1.tv_usec*1e-6);
00364         sentbytes = 0;
00365         while ((sentbytes < size) && !broken_pipe)
00366         {
00367                 int r = Send (s+sentbytes, size-sentbytes);
00368                 if (r > 0) sentbytes += r;
00369                 //printf("Sent %d ",sentbytes);
00370                 gettimeofday(&tv2,NULL);
00371                 t2ms = tv2.tv_sec+(tv2.tv_usec*1e-6);
00372                 dtms = t2ms - t1ms;
00373                 //printf("%f %f dtms : %f/%f\n",t1ms,t2ms,dtms,maxms);
00374                 
00375                 if (dtms >= maxms) break;
00376         }
00377         //printf(" Finally sent %d bytes\n",sentbytes);
00378         return (sentbytes == size);
00379 }
00380 
00381 
00382 bool Socket::PrepareServer()
00383 {
00384         if (!server) return false;
00385         if (accepting) return true;
00386 #ifdef TRACE
00387         printf("Opening server\n");
00388 #endif
00389         if (!Create()) return false;
00390 #ifdef TRACE
00391         printf("Create OK\n");
00392 #endif
00393         if (!Bind(port)) return false;
00394 #ifdef TRACE
00395         printf("Binding OK\n");
00396 #endif
00397         if (!Listen()) return false;
00398 #ifdef TRACE
00399         printf("Listening OK\n");
00400 #endif
00401         return true;
00402 }
00403 bool Socket::Open(Socket * newsocket)
00404 {
00405         if ((!server)||(!accepting)) return false;
00406         if (!Accept(newsocket)) return false;
00407 #ifdef TRACE
00408         printf("Accept OK\n");
00409 #endif
00410         return true;
00411 }
00412 
00413 //#define TRACE
00414 
00415 bool Socket::Open()
00416 {
00417         if (server)
00418         {
00419 #ifdef TRACE
00420                 printf("Opening server\n");
00421 #endif
00422                 Socket listener;
00423                 if (!listener.Create()) return false;
00424 #ifdef TRACE
00425                 printf("Create OK\n");
00426 #endif
00427                 if (!listener.Bind(port)) return false;
00428 #ifdef TRACE
00429                 printf("Binding OK\n");
00430 #endif
00431                 if (!listener.Listen()) return false;
00432 #ifdef TRACE
00433                 printf("Listening OK\n");
00434 #endif
00435                 if (!listener.Accept(*this)) return false;
00436 #ifdef TRACE
00437                 printf("Accept OK\n");
00438 #endif
00439         }
00440         else
00441         {
00442 #ifdef TRACE
00443                 printf("Opening client %s:%d\n",host,port);
00444 #endif
00445                 if (!Create()) return false;
00446 #ifdef TRACE
00447         printf("Create OK\n");
00448 #endif
00449                 if (!Connect(host,port)) return false;
00450 #ifdef TRACE
00451                 printf("Connect OK\n");
00452 #endif
00453                 SetNonBlocking(true);
00454         }
00455         return true;
00456 }
00457 
00458 


canon_vbc50i
Author(s): Cedric Pradalier
autogenerated on Mon Jan 6 2014 11:18:27