SUMO - Simulation of Urban MObility
socket.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ** This file is part of the network simulator Shawn. **
3  ** Copyright (C) 2004-2007 by the SwarmNet (www.swarmnet.de) project **
4  ** Shawn is free software; you can redistribute it and/or modify it **
5  ** under the terms of the BSD License. Refer to the shawn-licence.txt **
6  ** file in the root of the Shawn source tree for further details. **
7  ************************************************************************/
8 
9 #ifdef SHAWN
10  #include <apps/tcpip/socket.h>
11  #include <sys/simulation/simulation_controller.h>
12 #else
13  #include "socket.h"
14 #endif
15 
16 #ifdef BUILD_TCPIP
17 
18 
19 #ifndef WIN32
20  #include <sys/types.h>
21  #include <sys/socket.h>
22  #include <netinet/in.h>
23  #include <netinet/tcp.h>
24  #include <arpa/inet.h>
25  #include <netdb.h>
26  #include <errno.h>
27  #include <fcntl.h>
28  #include <unistd.h>
29 #else
30  #ifdef ERROR
31  #undef ERROR
32  #endif
33 
34  #include <winsock2.h>
35  #include <ws2tcpip.h>
36 
37  #ifndef vsnprintf
38  #define vsnprintf _vsnprintf
39  #endif
40 
41 #endif
42 
43 #include <cstdio>
44 #include <cstring>
45 #include <cstdarg>
46 #include <cassert>
47 #include <string>
48 #include <vector>
49 #include <string>
50 #include <algorithm>
51 #include <string.h>
52 
53 
54 #ifdef SHAWN
55  extern "C" void init_tcpip( shawn::SimulationController& sc )
56  {
57  // std::cout << "tcpip init" << std::endl;
58  }
59 #endif
60 
61 namespace tcpip
62 {
63  const int Socket::lengthLen = 4;
64 
65 #ifdef WIN32
66  bool Socket::init_windows_sockets_ = true;
67  bool Socket::windows_sockets_initialized_ = false;
68  int Socket::instance_count_ = 0;
69 #endif
70 
71  // ----------------------------------------------------------------------
72  Socket::
73  Socket(std::string host, int port)
74  : host_( host ),
75  port_( port ),
76  socket_(-1),
77  server_socket_(-1),
78  blocking_(true),
79  verbose_(false)
80  {
81  init();
82  }
83 
84  // ----------------------------------------------------------------------
85  Socket::
87  : host_(""),
88  port_( port ),
89  socket_(-1),
90  server_socket_(-1),
91  blocking_(true),
92  verbose_(false)
93  {
94  init();
95  }
96 
97  // ----------------------------------------------------------------------
98  void
99  Socket::
101  {
102 #ifdef WIN32
103  instance_count_++;
104 
105  if( init_windows_sockets_ && !windows_sockets_initialized_ )
106  {
107  WSAData wsaData;
108  if( WSAStartup(MAKEWORD(1, 1), &wsaData) != 0 )
109  BailOnSocketError("Unable to init WSA Sockets");
110  windows_sockets_initialized_ = true;
111  }
112 #endif
113  }
114 
115  // ----------------------------------------------------------------------
116  Socket::
118  {
119  // Close first an existing client connection ...
120  close();
121 #ifdef WIN32
122  instance_count_--;
123 #endif
124 
125  // ... then the server socket
126  if( server_socket_ >= 0 )
127  {
128 #ifdef WIN32
129  ::closesocket( server_socket_ );
130 #else
132 #endif
133  server_socket_ = -1;
134  }
135 
136 #ifdef WIN32
137  if( server_socket_ == -1 && socket_ == -1
138  && init_windows_sockets_ && instance_count_ == 0 )
139  WSACleanup();
140  windows_sockets_initialized_ = false;
141 #endif
142  }
143 
144  // ----------------------------------------------------------------------
145  void
146  Socket::
147  BailOnSocketError( std::string context)
148  const throw( SocketException )
149  {
150 #ifdef WIN32
151  int e = WSAGetLastError();
152  std::string msg = GetWinsockErrorString( e );
153 #else
154  std::string msg = strerror( errno );
155 #endif
156  throw SocketException( context + ": " + msg );
157  }
158 
159  // ----------------------------------------------------------------------
160  int
161  Socket::
163  {
164  return port_;
165  }
166 
167 
168  // ----------------------------------------------------------------------
169  bool
170  Socket::
171  datawaiting(int sock)
172  const throw()
173  {
174  fd_set fds;
175  FD_ZERO( &fds );
176  FD_SET( (unsigned int)sock, &fds );
177 
178  struct timeval tv;
179  tv.tv_sec = 0;
180  tv.tv_usec = 0;
181 
182  int r = select( sock+1, &fds, NULL, NULL, &tv);
183 
184  if (r < 0)
185  BailOnSocketError("tcpip::Socket::datawaiting @ select");
186 
187  if( FD_ISSET( sock, &fds ) )
188  return true;
189  else
190  return false;
191  }
192 
193  // ----------------------------------------------------------------------
194  bool
195  Socket::
196  atoaddr( std::string address, struct sockaddr_in& addr)
197  {
198  int status;
199  struct addrinfo *servinfo; // will point to the results
200 
201  struct addrinfo hints;
202  memset(&hints, 0, sizeof hints); // make sure the struct is empty
203  hints.ai_family = AF_INET; // restrict to IPv4?
204  hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
205  hints.ai_flags = AI_PASSIVE; // fill in my IP for me
206 
207  if ((status = getaddrinfo(address.c_str(), NULL, &hints, &servinfo)) != 0) {
208  return false;
209  }
210 
211  bool valid = false;
212 
213  for (struct addrinfo *p = servinfo; p != NULL; p = p->ai_next) {
214  if (p->ai_family == AF_INET) { // IPv4
215  addr = *(struct sockaddr_in *)p->ai_addr;
216  addr.sin_port = htons((unsigned short)port_);
217  valid = true;
218  break;
219  }
220  }
221 
222  freeaddrinfo(servinfo); // free the linked list
223 
224  return valid;
225  }
226 
227 
228  // ----------------------------------------------------------------------
229  Socket*
230  Socket::
231  accept(const bool create)
232  throw( SocketException )
233  {
234  if( socket_ >= 0 )
235  return 0;
236 
237  struct sockaddr_in client_addr;
238 #ifdef WIN32
239  int addrlen = sizeof(client_addr);
240 #else
241  socklen_t addrlen = sizeof(client_addr);
242 #endif
243 
244  if( server_socket_ < 0 )
245  {
246  struct sockaddr_in self;
247 
248  //Create the server socket
249  server_socket_ = static_cast<int>(socket( AF_INET, SOCK_STREAM, 0 ));
250  if( server_socket_ < 0 )
251  BailOnSocketError("tcpip::Socket::accept() @ socket");
252 
253  //"Address already in use" error protection
254  {
255 
256  #ifdef WIN32
257  //setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseaddr, sizeof(reuseaddr));
258  // No address reuse in Windows!!!
259  #else
260  int reuseaddr = 1;
261  setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr));
262  #endif
263  }
264 
265  // Initialize address/port structure
266  memset(&self, 0, sizeof(self));
267  self.sin_family = AF_INET;
268  self.sin_port = htons((unsigned short)port_);
269  self.sin_addr.s_addr = htonl(INADDR_ANY);
270 
271  // Assign a port number to the socket
272  if ( bind(server_socket_, (struct sockaddr*)&self, sizeof(self)) != 0 )
273  BailOnSocketError("tcpip::Socket::accept() Unable to create listening socket");
274 
275 
276  // Make it a "listening socket"
277  if ( listen(server_socket_, 10) == -1 )
278  BailOnSocketError("tcpip::Socket::accept() Unable to listen on server socket");
279 
280  // Make the newly created socket blocking or not
282  }
283 
284  socket_ = static_cast<int>(::accept(server_socket_, (struct sockaddr*)&client_addr, &addrlen));
285 
286  if( socket_ >= 0 )
287  {
288  int x = 1;
289  setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
290  if (create) {
291  Socket* result = new Socket(0);
292  result->socket_ = socket_;
293  socket_ = -1;
294  return result;
295  }
296  }
297  return 0;
298  }
299 
300  // ----------------------------------------------------------------------
301  void
302  Socket::
303  set_blocking(bool blocking)
304  throw(SocketException )
305  {
306  blocking_ = blocking;
307 
308  if( server_socket_ > 0 )
309  {
310 #ifdef WIN32
311  ULONG NonBlock = blocking_ ? 0 : 1;
312  if (ioctlsocket(server_socket_, FIONBIO, &NonBlock) == SOCKET_ERROR)
313  BailOnSocketError("tcpip::Socket::set_blocking() Unable to initialize non blocking I/O");
314 #else
315  long arg = fcntl(server_socket_, F_GETFL, NULL);
316  if (blocking_)
317  {
318  arg &= ~O_NONBLOCK;
319  } else {
320  arg |= O_NONBLOCK;
321  }
322  fcntl(server_socket_, F_SETFL, arg);
323 #endif
324  }
325 
326  }
327 
328  // ----------------------------------------------------------------------
329  void
330  Socket::
332  throw( SocketException )
333  {
334  sockaddr_in address;
335 
336  if( !atoaddr( host_.c_str(), address) )
337  BailOnSocketError("tcpip::Socket::connect() @ Invalid network address");
338 
339  socket_ = static_cast<int>(socket( PF_INET, SOCK_STREAM, 0 ));
340  if( socket_ < 0 )
341  BailOnSocketError("tcpip::Socket::connect() @ socket");
342 
343  if( ::connect( socket_, (sockaddr const*)&address, sizeof(address) ) < 0 )
344  BailOnSocketError("tcpip::Socket::connect() @ connect");
345 
346  if( socket_ >= 0 )
347  {
348  int x = 1;
349  setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (const char*)&x, sizeof(x));
350  }
351  }
352 
353  // ----------------------------------------------------------------------
354  void
355  Socket::
357  {
358  // Close client-connection
359  if( socket_ >= 0 )
360  {
361 #ifdef WIN32
362  ::closesocket( socket_ );
363 #else
364  ::close( socket_ );
365 #endif
366 
367  socket_ = -1;
368  }
369  }
370 
371  // ----------------------------------------------------------------------
372  void
373  Socket::
374  send( const std::vector<unsigned char> &buffer)
375  throw( SocketException )
376  {
377  if( socket_ < 0 )
378  return;
379 
380  printBufferOnVerbose(buffer, "Send");
381 
382  size_t numbytes = buffer.size();
383  unsigned char const *bufPtr = &buffer[0];
384  while( numbytes > 0 )
385  {
386 #ifdef WIN32
387  int bytesSent = ::send( socket_, (const char*)bufPtr, static_cast<int>(numbytes), 0 );
388 #else
389  int bytesSent = ::send( socket_, bufPtr, numbytes, 0 );
390 #endif
391  if( bytesSent < 0 )
392  BailOnSocketError( "send failed" );
393 
394  numbytes -= bytesSent;
395  bufPtr += bytesSent;
396  }
397  }
398 
399 
400 
401  // ----------------------------------------------------------------------
402 
403  void
404  Socket::
405  sendExact( const Storage &b)
406  throw( SocketException )
407  {
408  int length = static_cast<int>(b.size());
409  Storage length_storage;
410  length_storage.writeInt(lengthLen + length);
411 
412  // Sending length_storage and b independently would probably be possible and
413  // avoid some copying here, but both parts would have to go through the
414  // TCP/IP stack on their own which probably would cost more performance.
415  std::vector<unsigned char> msg;
416  msg.insert(msg.end(), length_storage.begin(), length_storage.end());
417  msg.insert(msg.end(), b.begin(), b.end());
418  send(msg);
419  }
420 
421 
422  // ----------------------------------------------------------------------
423  size_t
424  Socket::
425  recvAndCheck(unsigned char * const buffer, std::size_t len)
426  const
427  {
428 #ifdef WIN32
429  const int bytesReceived = recv( socket_, (char*)buffer, static_cast<int>(len), 0 );
430 #else
431  const int bytesReceived = static_cast<int>(recv( socket_, buffer, len, 0 ));
432 #endif
433  if( bytesReceived == 0 )
434  throw SocketException( "tcpip::Socket::recvAndCheck @ recv: peer shutdown" );
435  if( bytesReceived < 0 )
436  BailOnSocketError( "tcpip::Socket::recvAndCheck @ recv" );
437 
438  return static_cast<size_t>(bytesReceived);
439  }
440 
441 
442  // ----------------------------------------------------------------------
443  void
444  Socket::
445  receiveComplete(unsigned char * buffer, size_t len)
446  const
447  {
448  while (len > 0)
449  {
450  const size_t bytesReceived = recvAndCheck(buffer, len);
451  len -= bytesReceived;
452  buffer += bytesReceived;
453  }
454  }
455 
456 
457  // ----------------------------------------------------------------------
458  void
459  Socket::
460  printBufferOnVerbose(const std::vector<unsigned char> buffer, const std::string &label)
461  const
462  {
463  if (verbose_)
464  {
465  std::cerr << label << " " << buffer.size() << " bytes via tcpip::Socket: [";
466  // cache end iterator for performance
467  const std::vector<unsigned char>::const_iterator end = buffer.end();
468  for (std::vector<unsigned char>::const_iterator it = buffer.begin(); end != it; ++it)
469  std::cerr << " " << static_cast<int>(*it) << " ";
470  std::cerr << "]" << std::endl;
471  }
472  }
473 
474 
475  // ----------------------------------------------------------------------
476  std::vector<unsigned char>
477  Socket::
478  receive(int bufSize)
479  throw( SocketException )
480  {
481  std::vector<unsigned char> buffer;
482 
483  if( socket_ < 0 )
484  connect();
485 
486  if( !datawaiting( socket_) )
487  return buffer;
488 
489  buffer.resize(bufSize);
490  const size_t bytesReceived = recvAndCheck(&buffer[0], bufSize);
491 
492  buffer.resize(bytesReceived);
493 
494  printBufferOnVerbose(buffer, "Rcvd");
495 
496  return buffer;
497  }
498 
499  // ----------------------------------------------------------------------
500 
501 
502  bool
503  Socket::
505  throw( SocketException )
506  {
507  // buffer for received bytes
508  // According to the C++ standard elements of a std::vector are stored
509  // contiguously. Explicitly &buffer[n] == &buffer[0] + n for 0 <= n < buffer.size().
510  std::vector<unsigned char> buffer(lengthLen);
511 
512  // receive length of TraCI message
513  receiveComplete(&buffer[0], lengthLen);
514  Storage length_storage(&buffer[0], lengthLen);
515  const int totalLen = length_storage.readInt();
516  assert(totalLen > lengthLen);
517 
518  // extent buffer
519  buffer.resize(totalLen);
520 
521  // receive remaining TraCI message
522  receiveComplete(&buffer[lengthLen], totalLen - lengthLen);
523 
524  // copy message content into passed Storage
525  msg.reset();
526  msg.writePacket(&buffer[lengthLen], totalLen - lengthLen);
527 
528  printBufferOnVerbose(buffer, "Rcvd Storage with");
529 
530  return true;
531  }
532 
533 
534  // ----------------------------------------------------------------------
535  bool
536  Socket::
538  const
539  {
540  return socket_ >= 0;
541  }
542 
543  // ----------------------------------------------------------------------
544  bool
545  Socket::
547  throw()
548  {
549  return blocking_;
550  }
551 
552 
553 #ifdef WIN32
554  // ----------------------------------------------------------------------
555  std::string
556  Socket::
557  GetWinsockErrorString(int err)
558  const
559  {
560 
561  switch( err)
562  {
563  case 0: return "No error";
564  case WSAEINTR: return "Interrupted system call";
565  case WSAEBADF: return "Bad file number";
566  case WSAEACCES: return "Permission denied";
567  case WSAEFAULT: return "Bad address";
568  case WSAEINVAL: return "Invalid argument";
569  case WSAEMFILE: return "Too many open sockets";
570  case WSAEWOULDBLOCK: return "Operation would block";
571  case WSAEINPROGRESS: return "Operation now in progress";
572  case WSAEALREADY: return "Operation already in progress";
573  case WSAENOTSOCK: return "Socket operation on non-socket";
574  case WSAEDESTADDRREQ: return "Destination address required";
575  case WSAEMSGSIZE: return "Message too long";
576  case WSAEPROTOTYPE: return "Protocol wrong type for socket";
577  case WSAENOPROTOOPT: return "Bad protocol option";
578  case WSAEPROTONOSUPPORT: return "Protocol not supported";
579  case WSAESOCKTNOSUPPORT: return "Socket type not supported";
580  case WSAEOPNOTSUPP: return "Operation not supported on socket";
581  case WSAEPFNOSUPPORT: return "Protocol family not supported";
582  case WSAEAFNOSUPPORT: return "Address family not supported";
583  case WSAEADDRINUSE: return "Address already in use";
584  case WSAEADDRNOTAVAIL: return "Can't assign requested address";
585  case WSAENETDOWN: return "Network is down";
586  case WSAENETUNREACH: return "Network is unreachable";
587  case WSAENETRESET: return "Net Socket reset";
588  case WSAECONNABORTED: return "Software caused tcpip::Socket abort";
589  case WSAECONNRESET: return "Socket reset by peer";
590  case WSAENOBUFS: return "No buffer space available";
591  case WSAEISCONN: return "Socket is already connected";
592  case WSAENOTCONN: return "Socket is not connected";
593  case WSAESHUTDOWN: return "Can't send after socket shutdown";
594  case WSAETOOMANYREFS: return "Too many references, can't splice";
595  case WSAETIMEDOUT: return "Socket timed out";
596  case WSAECONNREFUSED: return "Socket refused";
597  case WSAELOOP: return "Too many levels of symbolic links";
598  case WSAENAMETOOLONG: return "File name too long";
599  case WSAEHOSTDOWN: return "Host is down";
600  case WSAEHOSTUNREACH: return "No route to host";
601  case WSAENOTEMPTY: return "Directory not empty";
602  case WSAEPROCLIM: return "Too many processes";
603  case WSAEUSERS: return "Too many users";
604  case WSAEDQUOT: return "Disc quota exceeded";
605  case WSAESTALE: return "Stale NFS file handle";
606  case WSAEREMOTE: return "Too many levels of remote in path";
607  case WSASYSNOTREADY: return "Network system is unavailable";
608  case WSAVERNOTSUPPORTED: return "Winsock version out of range";
609  case WSANOTINITIALISED: return "WSAStartup not yet called";
610  case WSAEDISCON: return "Graceful shutdown in progress";
611  case WSAHOST_NOT_FOUND: return "Host not found";
612  case WSANO_DATA: return "No host data of that type was found";
613  }
614 
615  return "unknown";
616  }
617 
618 #endif // WIN32
619 
620 } // namespace tcpip
621 
622 #endif // BUILD_TCPIP
623 
624 /*-----------------------------------------------------------------------
625 * Source $Source: $
626 * Version $Revision: 645 $
627 * Date $Date: 2012-04-27 14:03:33 +0200 (Fri, 27 Apr 2012) $
628 *-----------------------------------------------------------------------
629 * $Log: $
630 *-----------------------------------------------------------------------*/
Definition: socket.cpp:61
StorageType::const_iterator end() const
Definition: storage.h:118
void BailOnSocketError(std::string) const
Definition: socket.cpp:147
bool receiveExact(Storage &)
Receive a complete TraCI message from Socket::socket_.
Definition: socket.cpp:504
int server_socket_
Definition: socket.h:136
std::vector< unsigned char > receive(int bufSize=2048)
Receive up to bufSize available bytes from Socket::socket_.
Definition: socket.cpp:478
bool blocking_
Definition: socket.h:137
static const int lengthLen
Length of the message length part of a TraCI message.
Definition: socket.h:115
Socket(std::string host, int port)
Constructor that prepare to connect to host:port.
Definition: socket.cpp:73
bool has_client_connection() const
Definition: socket.cpp:537
virtual void writeInt(int)
void connect()
Connects to host_:port_.
Definition: socket.cpp:331
std::string host_
Definition: socket.h:133
void receiveComplete(unsigned char *const buffer, std::size_t len) const
Receive len bytes from Socket::socket_.
Definition: socket.cpp:445
virtual int readInt()
void printBufferOnVerbose(const std::vector< unsigned char > buffer, const std::string &label) const
Print label and buffer to stderr if Socket::verbose_ is set.
Definition: socket.cpp:460
~Socket()
Destructor.
Definition: socket.cpp:117
Socket * accept(const bool create=false)
Wait for a incoming connection to port_.
Definition: socket.cpp:231
void send(const std::vector< unsigned char > &buffer)
Definition: socket.cpp:374
void sendExact(const Storage &)
Definition: socket.cpp:405
bool is_blocking()
Definition: socket.cpp:546
StorageType::const_iterator begin() const
Definition: storage.h:117
bool atoaddr(std::string, struct sockaddr_in &addr)
Definition: socket.cpp:196
int port()
Definition: socket.cpp:162
void init()
Definition: socket.cpp:100
bool datawaiting(int sock) const
Definition: socket.cpp:171
bool verbose_
Definition: socket.h:139
int socket_
Definition: socket.h:135
void set_blocking(bool)
Definition: socket.cpp:303
void close()
Definition: socket.cpp:356
size_t recvAndCheck(unsigned char *const buffer, std::size_t len) const
Receive up to len available bytes from Socket::socket_.
Definition: socket.cpp:425