tcpip::Socket Class Reference

#include <socket.h>


Detailed Description

Definition at line 77 of file socket.h.


Public Member Functions

void accept () throw ( SocketException )
 Wait for a incoming connection to port_.
void close ()
void connect () throw ( SocketException )
 Connects to host_:port_.
bool has_client_connection () const
bool is_blocking () throw ()
int port ()
std::vector< unsigned char > receive (int bufSize=2048) throw ( SocketException )
bool receiveExact (Storage &) throw ( SocketException )
void send (const std::vector< unsigned char >) throw ( SocketException )
void sendExact (const Storage &) throw ( SocketException )
void set_blocking (bool) throw ( SocketException )
void set_verbose (bool newVerbose)
 Socket (int port)
 Constructor that prepare for accepting a connection on given port.
 Socket (std::string host, int port)
 Constructor that prepare to connect to host:port.
bool verbose ()
 ~Socket ()
 Destructor.

Private Member Functions

bool atoaddr (std::string, struct in_addr &addr)
void BailOnSocketError (std::string) const throw ( SocketException )
bool datawaiting (int sock) const throw ()
void init ()

Private Attributes

bool blocking_
std::string host_
int port_
int server_socket_
int socket_
bool verbose_

Friends

class Response

Constructor & Destructor Documentation

tcpip::Socket::Socket ( std::string  host,
int  port 
)

Constructor that prepare to connect to host:port.

Definition at line 70 of file socket.cpp.

References init(), and verbose_.

00071         : host_( host ),
00072         port_( port ),
00073         socket_(-1),
00074         server_socket_(-1),
00075         blocking_(true)
00076     {
00077         verbose_ = false;
00078         init();
00079     }

tcpip::Socket::Socket ( int  port  ) 

Constructor that prepare for accepting a connection on given port.

Definition at line 83 of file socket.cpp.

References init(), and verbose_.

00084         : host_(""),
00085         port_( port ),
00086         socket_(-1),
00087         server_socket_(-1),
00088         blocking_(true)
00089     {
00090         verbose_ = false;
00091         init();
00092     }

tcpip::Socket::~Socket (  ) 

Destructor.

Definition at line 114 of file socket.cpp.

References close(), server_socket_, and socket_.

00115     {
00116         // Close first an existing client connection ...
00117         close();
00118 #ifdef WIN32
00119         instance_count_--;
00120 #endif
00121 
00122         // ... then the server socket
00123         if( server_socket_ >= 0 )
00124         {
00125 #ifdef WIN32
00126             ::closesocket( server_socket_ );
00127 #else
00128 			::close( server_socket_ );
00129 #endif
00130             server_socket_ = -1;
00131         }
00132 
00133 #ifdef WIN32
00134         if( server_socket_ == -1 && socket_ == -1 
00135             && init_windows_sockets_ && instance_count_ == 0 )
00136                 WSACleanup();
00137                 windows_sockets_initialized_ = false;
00138 #endif
00139     }


Member Function Documentation

void tcpip::Socket::accept (  )  throw ( SocketException )

Wait for a incoming connection to port_.

Definition at line 219 of file socket.cpp.

References BailOnSocketError(), blocking_, port_, server_socket_, set_blocking(), and socket_.

00221     {
00222         if( socket_ >= 0 )
00223             return;
00224 
00225         struct sockaddr_in client_addr;
00226 #ifdef WIN32
00227         int addrlen = sizeof(client_addr);
00228 #else
00229         socklen_t addrlen = sizeof(client_addr);
00230 #endif
00231 
00232         if( server_socket_ < 0 )
00233         {
00234             struct sockaddr_in self;
00235 
00236             //Create the server socket
00237             server_socket_ = static_cast<int>(socket( AF_INET, SOCK_STREAM, 0 ));
00238             if( server_socket_ < 0 )
00239                 BailOnSocketError("tcpip::Socket::accept() @ socket");
00240             
00241             //"Address already in use" error protection
00242             {
00243                 int reuseaddr = 1;
00244 
00245                 #ifdef WIN32
00246                     //setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
00247                     // No address reuse in Windows!!!
00248                 #else
00249                     setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
00250                 #endif
00251             }
00252 
00253             // Initialize address/port structure
00254             memset(&self, 0, sizeof(self));
00255             self.sin_family = AF_INET;
00256             self.sin_port = htons(port_);
00257             self.sin_addr.s_addr = htonl(INADDR_ANY);
00258 
00259             // Assign a port number to the socket
00260             if ( bind(server_socket_, (struct sockaddr*)&self, sizeof(self)) != 0 )
00261                 BailOnSocketError("tcpip::Socket::accept() Unable to create listening socket");
00262 
00263 
00264             // Make it a "listening socket"
00265             if ( listen(server_socket_, 10) == -1 )
00266                 BailOnSocketError("tcpip::Socket::accept() Unable to listen on server socket");
00267 
00268             // Make the newly created socket blocking or not
00269             set_blocking(blocking_);
00270         }
00271 
00272         socket_ = static_cast<int>(::accept(server_socket_, (struct sockaddr*)&client_addr, &addrlen));
00273 
00274         if( socket_ >= 0 )
00275         {
00276             int x = 1;
00277             setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
00278         }
00279     }

bool tcpip::Socket::atoaddr ( std::string  address,
struct in_addr &  addr 
) [private]

Definition at line 193 of file socket.cpp.

Referenced by connect().

00194     {
00195         struct hostent* host;
00196         struct in_addr saddr;
00197 
00198         // First try nnn.nnn.nnn.nnn form
00199         saddr.s_addr = inet_addr(address.c_str());
00200         if (saddr.s_addr != static_cast<unsigned int>(-1)) 
00201         {
00202             addr = saddr;
00203             return true;
00204         }
00205 
00206         host = gethostbyname(address.c_str());
00207         if( host ) {
00208             addr = *((struct in_addr*)host->h_addr_list[0]);
00209             return true;
00210         }
00211 
00212         return false;
00213     }

void tcpip::Socket::BailOnSocketError ( std::string  context  )  const throw ( SocketException ) [private]

Definition at line 144 of file socket.cpp.

Referenced by accept(), connect(), datawaiting(), init(), receive(), receiveExact(), send(), and set_blocking().

00146     {
00147 #ifdef WIN32
00148         int e = WSAGetLastError();
00149         std::string msg = GetWinsockErrorString( e );
00150 #else
00151         std::string msg = strerror( errno );
00152 #endif
00153         throw SocketException( context + ": " + msg );
00154     }

void tcpip::Socket::close (  ) 

Definition at line 343 of file socket.cpp.

References socket_.

Referenced by testclient::TraCITestClient::close(), OutputDevice_Network::~OutputDevice_Network(), and ~Socket().

00344     {
00345         // Close client-connection 
00346         if( socket_ >= 0 )
00347         {
00348 #ifdef WIN32
00349             ::closesocket( socket_ );
00350 #else
00351 			::close( socket_ );
00352 #endif
00353 
00354             socket_ = -1;
00355         }
00356     }

void tcpip::Socket::connect (  )  throw ( SocketException )

Connects to host_:port_.

Definition at line 312 of file socket.cpp.

References atoaddr(), BailOnSocketError(), host_, port_, and socket_.

Referenced by testclient::TraCITestClient::connect(), and receive().

00314     {
00315         in_addr addr;
00316         if( !atoaddr( host_.c_str(), addr) )
00317             BailOnSocketError("tcpip::Socket::connect() @ Invalid network address");
00318 
00319         sockaddr_in address;
00320         memset( (char*)&address, 0, sizeof(address) );
00321         address.sin_family = AF_INET;
00322         address.sin_port = htons( port_ );
00323         address.sin_addr.s_addr = addr.s_addr;
00324 
00325         socket_ = static_cast<int>(socket( PF_INET, SOCK_STREAM, 0 ));
00326         if( socket_ < 0 )
00327             BailOnSocketError("tcpip::Socket::connect() @ socket");
00328 
00329         if( ::connect( socket_, (sockaddr const*)&address, sizeof(address) ) < 0 )
00330             BailOnSocketError("tcpip::Socket::connect() @ connect");
00331 
00332         if( socket_ >= 0 )
00333         {
00334             int x = 1;
00335             setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
00336         }
00337 
00338     }

bool tcpip::Socket::datawaiting ( int  sock  )  const throw () [private]

Definition at line 168 of file socket.cpp.

References BailOnSocketError().

Referenced by receive().

00170     {
00171         fd_set fds;
00172         FD_ZERO( &fds );
00173         FD_SET( sock, &fds );
00174 
00175         struct timeval tv;
00176         tv.tv_sec = 0;
00177         tv.tv_usec = 0;
00178 
00179         int r = select( sock+1, &fds, NULL, NULL, &tv);
00180 
00181         if (r < 0)
00182             BailOnSocketError("tcpip::Socket::datawaiting @ select");
00183 
00184         if( FD_ISSET( sock, &fds ) )
00185             return true;
00186         else
00187             return false;
00188     }

bool tcpip::Socket::has_client_connection (  )  const

Definition at line 545 of file socket.cpp.

References socket_.

00547     {
00548         return socket_ >= 0;
00549     }

void tcpip::Socket::init (  )  [private]

Definition at line 97 of file socket.cpp.

References BailOnSocketError().

Referenced by Socket().

00098     {
00099 #ifdef WIN32
00100         instance_count_++;
00101 
00102         if( init_windows_sockets_ && !windows_sockets_initialized_ )
00103         {
00104             WSAData wsaData;
00105             if( WSAStartup(MAKEWORD(1, 1), &wsaData) != 0 )
00106                 BailOnSocketError("Unable to init WSA Sockets");
00107             windows_sockets_initialized_ = true;
00108         }
00109 #endif
00110     }

bool tcpip::Socket::is_blocking (  )  throw ()

Definition at line 554 of file socket.cpp.

References blocking_.

00556     {
00557         return blocking_;
00558     }

int tcpip::Socket::port (  ) 

Definition at line 159 of file socket.cpp.

References port_.

00160     {
00161         return port_;
00162     }

vector< unsigned char > tcpip::Socket::receive ( int  bufSize = 2048  )  throw ( SocketException )

Definition at line 430 of file socket.cpp.

References BailOnSocketError(), connect(), datawaiting(), socket_, and verbose_.

00432     {
00433         vector<unsigned char> b;
00434 
00435         if( socket_ < 0 )
00436             connect();
00437 
00438         if( !datawaiting( socket_) )
00439             return b;
00440 
00441         unsigned char const * const buf = new unsigned char[bufSize];
00442         int a = recv( socket_, (char*)buf, bufSize, 0 );
00443 
00444         if( a <= 0 )
00445         {
00446             // BailOnSocketError definitely throws an exception so clear up heap
00447             delete[] buf;
00448             BailOnSocketError( "tcpip::Socket::receive() @ recv" );
00449         }
00450 
00451         b.resize(a);
00452         for(int i = 0; i < a; ++i)
00453         {
00454             b[i] = buf[i];
00455         }
00456 
00457         if (verbose_) 
00458         {
00459             cerr << "Rcvd "  << a <<  " bytes via tcpip::Socket: [";
00460             for(int i = 0; i < a; ++i)
00461             {
00462                 cerr << " " << (int)b[i] << " ";
00463             }
00464             cerr << "]" << endl;
00465         }
00466 
00467         delete[] buf;
00468         return b;
00469     }

bool tcpip::Socket::receiveExact ( Storage msg  )  throw ( SocketException )

Definition at line 476 of file socket.cpp.

References BailOnSocketError(), tcpip::Storage::readInt(), socket_, and verbose_.

Referenced by testclient::TraCITestClient::commandChangeLane(), testclient::TraCITestClient::commandChangeRoute(), testclient::TraCITestClient::commandChangeTarget(), testclient::TraCITestClient::commandClose(), testclient::TraCITestClient::commandDistanceRequest(), testclient::TraCITestClient::commandGetTLStatus(), testclient::TraCITestClient::commandGetVariable(), testclient::TraCITestClient::commandGetVariablePlus(), testclient::TraCITestClient::commandPositionConversion(), testclient::TraCITestClient::commandScenario(), testclient::TraCITestClient::commandSetMaximumSpeed(), testclient::TraCITestClient::commandSetValue(), testclient::TraCITestClient::commandSimulationStep(), testclient::TraCITestClient::commandSimulationStep2(), testclient::TraCITestClient::commandSlowDown(), testclient::TraCITestClient::commandStopNode(), and testclient::TraCITestClient::commandSubscribeVariable().

00478     {
00479         /* receive length of vector */
00480         unsigned char * const bufLength = new unsigned char[4];
00481         int bytesRead = 0;
00482         int readThisTime = 0;
00483         
00484         while (bytesRead<4)
00485         {
00486             readThisTime = recv( socket_, (char*)(bufLength + bytesRead), 4-bytesRead, 0 );
00487 
00488             if( readThisTime <= 0 )
00489             {
00490                 // BailOnSocketError definitely throws an exception so clear up heap
00491                 delete[] bufLength;
00492                 BailOnSocketError( "tcpip::Socket::receive() @ recv" );
00493             }
00494 
00495             bytesRead += readThisTime;
00496         }
00497         Storage length_storage(bufLength,4);
00498         int NN = length_storage.readInt() - 4;
00499 
00500         /* receive vector */
00501         unsigned char * const buf = new unsigned char[NN];
00502         bytesRead = 0;
00503         readThisTime = 0;
00504         
00505         while (bytesRead<NN)
00506         {
00507             readThisTime = recv( socket_, (char*)(buf + bytesRead), NN-bytesRead, 0 );
00508 
00509             if( readThisTime <= 0 )
00510             {
00511                 // BailOnSocketError definitely throws an exception so clear up heap
00512                 delete[] bufLength;
00513                 delete[] buf;
00514                 BailOnSocketError( "tcpip::Socket::receive() @ recv" );
00515             }
00516 
00517             bytesRead += readThisTime;
00518         }
00519         msg.reset();
00520         msg.writePacket(buf, NN);
00521         
00522         if (verbose_)
00523         {
00524             cerr << "Rcvd Storage with "  << 4 + NN <<  " bytes via tcpip::Socket: [";
00525             for (int i=0; i < 4; ++i)
00526             {
00527                 cerr << " " << (int)bufLength[i] << " ";
00528             }
00529             for (int i=0; i < NN; ++i)
00530             {
00531                 cerr << " " << (int)buf[i] << " ";
00532             }
00533             cerr << "]" << endl;
00534         }
00535 
00536         delete[] buf;
00537         delete[] bufLength;
00538         return true;
00539     }

void tcpip::Socket::send ( const std::vector< unsigned char >  b  )  throw ( SocketException )

Definition at line 361 of file socket.cpp.

References BailOnSocketError(), socket_, and verbose_.

Referenced by OutputDevice_Network::postWriteHook(), and sendExact().

00363     {
00364         if( socket_ < 0 ) return;
00365 
00366         size_t numbytes = b.size();
00367         unsigned char *const buf = new unsigned char[numbytes];
00368 
00369         for(size_t i = 0; i < numbytes; ++i)
00370         {
00371             buf[i] = b[i];
00372         }
00373 
00374         if (verbose_) 
00375         {
00376             cerr << "Send " << numbytes << " bytes via tcpip::Socket: [";
00377             for(size_t i = 0; i < numbytes; ++i)
00378             {
00379                 buf[i] = b[i];
00380                 cerr << " " << (int)b[i] << " ";
00381             }
00382             cerr << "]" << endl;
00383         }
00384 
00385         unsigned char const *buf_ptr = buf;
00386         while( numbytes > 0 )
00387         {
00388 #ifdef WIN32
00389             int n = ::send( socket_, (const char*)buf_ptr, static_cast<int>(numbytes), 0 );
00390 #else
00391             int n = ::send( socket_, buf_ptr, numbytes, 0 );
00392 #endif
00393             if( n<0 )
00394             {
00395                 // BailOnSocketError definitely throws an exception so clear up heap
00396                 delete[] buf;
00397                 BailOnSocketError( "send failed" );
00398             }
00399 
00400             numbytes -= n;
00401             buf_ptr += n;
00402         }
00403 
00404         delete[] buf;
00405     }

void tcpip::Socket::sendExact ( const Storage b  )  throw ( SocketException )

void tcpip::Socket::set_blocking ( bool  blocking  )  throw ( SocketException )

Definition at line 284 of file socket.cpp.

References BailOnSocketError(), blocking_, and server_socket_.

Referenced by accept().

00286     {
00287         blocking_ = blocking;
00288 
00289         if( server_socket_ > 0 )
00290         {
00291 #ifdef WIN32
00292             ULONG NonBlock = blocking_ ? 0 : 1;
00293             if (ioctlsocket(server_socket_, FIONBIO, &NonBlock) == SOCKET_ERROR)
00294                 BailOnSocketError("tcpip::Socket::set_blocking() Unable to initialize non blocking I/O");
00295 #else
00296             long arg = fcntl(server_socket_, F_GETFL, NULL);
00297             if (blocking_)
00298             {
00299                 arg &= ~O_NONBLOCK;
00300             } else {
00301                 arg |= O_NONBLOCK;
00302             }
00303             fcntl(server_socket_, F_SETFL, arg);
00304 #endif
00305         }
00306     
00307     }

void tcpip::Socket::set_verbose ( bool  newVerbose  )  [inline]

Definition at line 108 of file socket.h.

References verbose_.

00108 { verbose_ = newVerbose; }

bool tcpip::Socket::verbose (  )  [inline]

Definition at line 107 of file socket.h.

References verbose_.

00107 { return verbose_; }


Friends And Related Function Documentation

friend class Response [friend]

Definition at line 79 of file socket.h.


Field Documentation

Definition at line 123 of file socket.h.

Referenced by accept(), is_blocking(), and set_blocking().

std::string tcpip::Socket::host_ [private]

Definition at line 119 of file socket.h.

Referenced by connect().

int tcpip::Socket::port_ [private]

Definition at line 120 of file socket.h.

Referenced by accept(), connect(), and port().

Definition at line 122 of file socket.h.

Referenced by accept(), set_blocking(), and ~Socket().

int tcpip::Socket::socket_ [private]

Definition at line 121 of file socket.h.

Referenced by accept(), close(), connect(), has_client_connection(), receive(), receiveExact(), send(), and ~Socket().

Definition at line 125 of file socket.h.

Referenced by receive(), receiveExact(), send(), set_verbose(), Socket(), and verbose().


The documentation for this class was generated from the following files:

Generated on Wed May 5 00:07:02 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6