WindowsSocket.cpp
Go to the documentation of this file.
1 
26 #include "WindowsSocket.h"
27 #include <string>
28 #include <iostream>
29 #include <winsock2.h>
30 #include <ws2tcpip.h>
31 
32 #pragma comment(lib, "Ws2_32.lib")
33 
34 #define DEFAULT_PORT "11411"
35 
36 using std::string;
37 using std::cerr;
38 using std::endl;
39 
40 
42 {
43 
44 public:
45 
46  WindowsSocketImpl () : mySocket (INVALID_SOCKET)
47  { }
48 
49  void init (char *server_hostname)
50  {
51  WSADATA wsaData;
52  int result = WSAStartup (MAKEWORD (2, 2), &wsaData);
53  if (result)
54  {
55  // TODO: do something more useful here with the error code
56  std::cerr << "Could not initialize windows socket (" << result << ")" << std::endl;
57  return;
58  }
59 
60  struct addrinfo *servers = get_server_addr (server_hostname);
61 
62  if (NULL == servers)
63  {
64  WSACleanup ();
65  return;
66  }
67 
68  connect_to_server (servers);
69 
70  freeaddrinfo (servers);
71 
72  if (INVALID_SOCKET == mySocket)
73  {
74  std::cerr << "Could not connect to server" << std::endl;
75  WSACleanup ();
76  }
77  }
78 
79  int read ()
80  {
81  char data;
82  int result = recv (mySocket, &data, 1, 0);
83  if (result < 0)
84  {
85  if (WSAEWOULDBLOCK != WSAGetLastError())
86  {
87  std::cerr << "Failed to receive data from server " << WSAGetLastError() << std::endl;
88  }
89  return -1;
90  }
91  else if (result == 0)
92  {
93  std::cerr << "Connection to server closed" << std::endl;
94  return -1;
95  }
96  return (unsigned char) data;
97  }
98 
99  void write (const unsigned char *data, int length)
100  {
101  int result = send (mySocket, (const char *) data, length, 0);
102  if (SOCKET_ERROR == result)
103  {
104  std::cerr << "Send failed with error " << WSAGetLastError () << std::endl;
105  closesocket (mySocket);
106  WSACleanup ();
107  }
108  }
109 
110  unsigned long time ()
111  {
112  SYSTEMTIME st_now;
113  GetSystemTime (&st_now);
114  unsigned long millis = st_now.wHour * 3600000 +
115  st_now.wMinute * 60000 +
116  st_now.wSecond * 1000 +
117  st_now.wMilliseconds;
118  return millis;
119  }
120 
121 protected:
129  struct addrinfo *get_server_addr (const string & hostname)
130  {
131  int result;
132  struct addrinfo *ai_output = NULL;
133  struct addrinfo ai_input;
134 
135  // split off the port number if given
136  int c = hostname.find_last_of (':');
137  string host = hostname.substr (0, c);
138  string port = (c < 0) ? DEFAULT_PORT : hostname.substr (c + 1);
139 
140  ZeroMemory (&ai_input, sizeof (ai_input));
141  ai_input.ai_family = AF_UNSPEC;
142  ai_input.ai_socktype = SOCK_STREAM;
143  ai_input.ai_protocol = IPPROTO_TCP;
144 
145  // Resolve the server address and port
146  result = getaddrinfo (host.c_str (), port.c_str (), &ai_input, &ai_output);
147  if (result != 0)
148  {
149  std::cerr << "Could not resolve server address (" << result << ")" << std::endl;
150  return NULL;
151  }
152  return ai_output;
153  }
154 
159  void connect_to_server (struct addrinfo *servers)
160  {
161  int result;
162  for (struct addrinfo * ptr = servers; ptr != NULL; ptr = ptr->ai_next)
163  {
164  mySocket = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
165  if (INVALID_SOCKET == mySocket)
166  {
167  std::cerr << "Could not great socket " << WSAGetLastError ();
168  return;
169  }
170 
171  result = connect (mySocket, ptr->ai_addr, (int) ptr->ai_addrlen);
172  if (SOCKET_ERROR == result)
173  {
174  closesocket (mySocket);
175  mySocket = INVALID_SOCKET;
176  }
177  else
178  {
179  break;
180  }
181  }
182 
183  // disable nagle's algorithm
184  char value = 1;
185  setsockopt (mySocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value));
186  // disable blocking
187  u_long iMode = 1;
188  result = ioctlsocket (mySocket, FIONBIO, &iMode);
189  if (result)
190  {
191  std::cerr << "Could not make socket nonblocking " << result << std::endl;
192  closesocket (mySocket);
193  mySocket = INVALID_SOCKET;
194  }
195  }
196 
197 private:
198  SOCKET mySocket;
199 };
200 
202 {
203  impl = new WindowsSocketImpl ();
204 }
205 
206 void WindowsSocket::init (char *server_hostname)
207 {
208  impl->init (server_hostname);
209 }
210 
212 {
213  return impl->read ();
214 }
215 
216 void WindowsSocket::write (const unsigned char *data, int length)
217 {
218  impl->write (data, length);
219 }
220 
221 unsigned long WindowsSocket::time ()
222 {
223  return impl->time ();
224 }
struct addrinfo * get_server_addr(const string &hostname)
void init(char *server_hostname)
void init(char *server_hostname)
void connect_to_server(struct addrinfo *servers)
unsigned long time()
#define DEFAULT_PORT
void write(const unsigned char *data, int length)
void write(const unsigned char *data, int length)
unsigned long time()


rosserial_windows
Author(s): Kareem Shehata
autogenerated on Fri Jun 7 2019 22:03:10