WindowsSocket.cpp
Go to the documentation of this file.
00001 
00026 #include "WindowsSocket.h"
00027 #include <string>
00028 #include <iostream>
00029 #include <winsock2.h>
00030 #include <ws2tcpip.h>
00031 
00032 #pragma comment(lib, "Ws2_32.lib")
00033 
00034 #define DEFAULT_PORT "11411"
00035 
00036 using std::string;
00037 using std::cerr;
00038 using std::endl;
00039 
00040 
00041 class WindowsSocketImpl
00042 {
00043 
00044 public:
00045 
00046   WindowsSocketImpl () : mySocket (INVALID_SOCKET)
00047   { }
00048 
00049   void init (char *server_hostname)
00050   {
00051     WSADATA wsaData;
00052     int result = WSAStartup (MAKEWORD (2, 2), &wsaData);
00053     if (result)
00054     {
00055       // TODO: do something more useful here with the error code
00056       std::cerr << "Could not initialize windows socket (" << result << ")" << std::endl;
00057       return;
00058     }
00059 
00060     struct addrinfo *servers = get_server_addr (server_hostname);
00061 
00062     if (NULL == servers)
00063     {
00064       WSACleanup ();
00065       return;
00066     }
00067 
00068     connect_to_server (servers);
00069 
00070     freeaddrinfo (servers);
00071 
00072     if (INVALID_SOCKET == mySocket)
00073     {
00074       std::cerr << "Could not connect to server" << std::endl;
00075       WSACleanup ();
00076     }
00077   }
00078 
00079   int read ()
00080   {
00081     char data;
00082     int result = recv (mySocket, &data, 1, 0);
00083     if (result < 0)
00084     {
00085       if (WSAEWOULDBLOCK != WSAGetLastError())
00086       {
00087         std::cerr << "Failed to receive data from server " << WSAGetLastError() << std::endl;
00088       }
00089       return -1;
00090     }
00091     else if (result == 0)
00092     {
00093       std::cerr << "Connection to server closed" << std::endl;
00094       return -1;
00095     }
00096     return (unsigned char) data;
00097   }
00098 
00099   void write (const unsigned char *data, int length)
00100   {
00101     int result = send (mySocket, (const char *) data, length, 0);
00102     if (SOCKET_ERROR == result)
00103     {
00104       std::cerr << "Send failed with error " << WSAGetLastError () << std::endl;
00105       closesocket (mySocket);
00106       WSACleanup ();
00107     }
00108   }
00109 
00110   unsigned long time ()
00111   {
00112     SYSTEMTIME st_now;
00113     GetSystemTime (&st_now);
00114     unsigned long millis = st_now.wHour * 3600000 +
00115                            st_now.wMinute * 60000 + 
00116                            st_now.wSecond * 1000 + 
00117                            st_now.wMilliseconds;
00118     return millis;
00119   }
00120 
00121 protected:
00129   struct addrinfo *get_server_addr (const string & hostname)
00130   {
00131     int result;
00132     struct addrinfo *ai_output = NULL;
00133     struct addrinfo ai_input;
00134 
00135     // split off the port number if given
00136     int c = hostname.find_last_of (':');
00137     string host = hostname.substr (0, c);
00138     string port = (c < 0) ? DEFAULT_PORT : hostname.substr (c + 1);
00139 
00140     ZeroMemory (&ai_input, sizeof (ai_input));
00141     ai_input.ai_family = AF_UNSPEC;
00142     ai_input.ai_socktype = SOCK_STREAM;
00143     ai_input.ai_protocol = IPPROTO_TCP;
00144 
00145     // Resolve the server address and port
00146     result = getaddrinfo (host.c_str (), port.c_str (), &ai_input, &ai_output);
00147     if (result != 0)
00148     {
00149       std::cerr << "Could not resolve server address (" << result << ")" << std::endl;
00150       return NULL;
00151     }
00152     return ai_output;
00153   }
00154 
00159   void connect_to_server (struct addrinfo *servers)
00160   {
00161     int result;
00162     for (struct addrinfo * ptr = servers; ptr != NULL; ptr = ptr->ai_next)
00163     {
00164       mySocket = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
00165       if (INVALID_SOCKET == mySocket)
00166       {
00167         std::cerr << "Could not great socket " << WSAGetLastError ();
00168         return;
00169       }
00170 
00171       result = connect (mySocket, ptr->ai_addr, (int) ptr->ai_addrlen);
00172       if (SOCKET_ERROR == result)
00173       {
00174         closesocket (mySocket);
00175         mySocket = INVALID_SOCKET;
00176       }
00177       else
00178       {
00179         break;
00180       }
00181     }
00182 
00183     // disable nagle's algorithm
00184     char value = 1;
00185     setsockopt (mySocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value));
00186     // disable blocking
00187     u_long iMode = 1;
00188     result = ioctlsocket (mySocket, FIONBIO, &iMode);
00189     if (result)
00190     {
00191       std::cerr << "Could not make socket nonblocking " << result << std::endl;
00192       closesocket (mySocket);
00193       mySocket = INVALID_SOCKET;
00194     }
00195   }
00196 
00197 private:
00198   SOCKET mySocket;
00199 };
00200 
00201 WindowsSocket::WindowsSocket ()
00202 {
00203   impl = new WindowsSocketImpl ();
00204 }
00205 
00206 void WindowsSocket::init (char *server_hostname)
00207 {
00208   impl->init (server_hostname);
00209 }
00210 
00211 int WindowsSocket::read ()
00212 {
00213   return impl->read ();
00214 }
00215 
00216 void WindowsSocket::write (const unsigned char *data, int length)
00217 {
00218   impl->write (data, length);
00219 }
00220 
00221 unsigned long WindowsSocket::time ()
00222 {
00223   return impl->time ();
00224 }


rosserial_windows
Author(s): Kareem Shehata
autogenerated on Fri Aug 28 2015 12:44:58