win32/net_socket.cpp
Go to the documentation of this file.
1 /*
2  * RoboPeak Project
3  * HAL Layer - Socket Interface
4  * Copyright 2009 - 2013 RoboPeak Project
5  *
6  * Win32 Implementation
7  */
8 
9 #define _WINSOCKAPI_
10 
11 #include "sdkcommon.h"
12 #include "..\..\hal\socket.h"
13 #include <windows.h>
14 #include <winsock2.h>
15 #include <ws2tcpip.h>
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #pragma comment (lib, "Ws2_32.lib")
20 
21 namespace rp{ namespace net {
22 
23 static volatile bool _isWSAStartupCalled = false;
24 
25 static inline bool _checkWSAStartup() {
26  int iResult;
27  WSADATA wsaData;
28  if (!_isWSAStartupCalled) {
29  iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
30  if (iResult != 0) {
31  return false;
32  }
33  _isWSAStartupCalled = true;
34  }
35  return true;
36 }
37 
38 static const char* _inet_ntop(int af, const void* src, char* dst, int cnt){
39 
40  struct sockaddr_storage srcaddr;
41 
42 
43  memset(dst, 0, cnt);
44 
45  memset(&srcaddr, 0, sizeof(struct sockaddr_storage));
46 
47 
48  srcaddr.ss_family = af;
49 
50  switch (af) {
51  case AF_INET:
52  {
53  struct sockaddr_in * ipv4 = reinterpret_cast< struct sockaddr_in *>(&srcaddr);
54  memcpy(&(ipv4->sin_addr), src, sizeof(ipv4->sin_addr));
55  }
56  break;
57  case AF_INET6:
58  {
59  struct sockaddr_in6 * ipv6 = reinterpret_cast< struct sockaddr_in6 *>(&srcaddr);
60  memcpy(&(ipv6->sin6_addr), src, sizeof(ipv6->sin6_addr));
61  }
62  break;
63  }
64 
65  if (WSAAddressToStringA((struct sockaddr*) &srcaddr, sizeof(struct sockaddr_storage), 0, dst, (LPDWORD) &cnt) != 0) {
66  DWORD rv = WSAGetLastError();
67  return NULL;
68  }
69  return dst;
70 }
71 
72 static int _inet_pton(int Family, const char * pszAddrString, void* pAddrBuf)
73 {
74  struct sockaddr_storage tmpholder;
75  int actualSize = sizeof(sockaddr_storage);
76 
77  int result = WSAStringToAddressA((char *)pszAddrString, Family, NULL, (sockaddr*)&tmpholder, &actualSize);
78  if (result) return -1;
79 
80  switch (Family) {
81  case AF_INET:
82  {
83  struct sockaddr_in * ipv4 = reinterpret_cast< struct sockaddr_in *>(&tmpholder);
84  memcpy(pAddrBuf, &(ipv4->sin_addr), sizeof(ipv4->sin_addr));
85  }
86  break;
87  case AF_INET6:
88  {
89  struct sockaddr_in6 * ipv6 = reinterpret_cast< struct sockaddr_in6 *>(&tmpholder);
90  memcpy(pAddrBuf, &(ipv6->sin6_addr), sizeof(ipv6->sin6_addr));
91  }
92  break;
93  }
94  return 1;
95 }
96 
98 {
99  switch (type) {
101  return AF_INET;
103  return AF_INET6;
105  return AF_UNSPEC;
106 
107  default:
108  assert(!"should not reach here");
109  return AF_UNSPEC;
110  }
111 }
112 
113 
115 {
117  _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
118  memset(_platform_data, 0, sizeof(sockaddr_storage));
119 
120  reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
121 }
122 
124 {
125  _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
126  memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
127 }
128 
129 
130 
131 SocketAddress::SocketAddress(const char * addrString, int port, SocketAddress::address_type_t type)
132 {
134  _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
135  memset(_platform_data, 0, sizeof(sockaddr_storage));
136 
137  // default to ipv4 in case the following operation fails
138  reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
139 
140  setAddressFromString(addrString, type);
141  setPort(port);
142 }
143 
144 SocketAddress::SocketAddress(void * platform_data)
145  : _platform_data(platform_data)
146 { _checkWSAStartup(); }
147 
149 {
150  memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
151  return *this;
152 }
153 
154 
156 {
157  delete reinterpret_cast<sockaddr_storage *>(_platform_data);
158 }
159 
161 {
162  switch(reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family) {
163  case AF_INET:
164  return ADDRESS_TYPE_INET;
165  case AF_INET6:
166  return ADDRESS_TYPE_INET6;
167  default:
168  assert(!"should not reach here");
169  return ADDRESS_TYPE_INET;
170  }
171 }
172 
173 int SocketAddress::getPort() const
174 {
175  switch (getAddressType()) {
176  case ADDRESS_TYPE_INET:
177  return (int)ntohs(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_port);
178  case ADDRESS_TYPE_INET6:
179  return (int)ntohs(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_port);
180  default:
181  return 0;
182  }
183 }
184 
186 {
187  switch (getAddressType()) {
188  case ADDRESS_TYPE_INET:
189  reinterpret_cast<sockaddr_in *>(_platform_data)->sin_port = htons((short)port);
190  break;
191  case ADDRESS_TYPE_INET6:
192  reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_port = htons((short)port);
193  break;
194  default:
195  return RESULT_OPERATION_FAIL;
196  }
197  return RESULT_OK;
198 }
199 
201 {
202  int ans = 0;
203  int prevPort = getPort();
204  switch (type) {
205  case ADDRESS_TYPE_INET:
206  reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
207  ans = _inet_pton(AF_INET,
208  address_string,
209  &reinterpret_cast<sockaddr_in *>(_platform_data)->sin_addr);
210  break;
211 
212 
213  case ADDRESS_TYPE_INET6:
214 
215  reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET6;
216  ans = _inet_pton(AF_INET6,
217  address_string,
218  &reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_addr);
219  break;
220 
221  default:
222  return RESULT_INVALID_DATA;
223 
224  }
225  setPort(prevPort);
226 
227  return ans<=0?RESULT_INVALID_DATA:RESULT_OK;
228 }
229 
230 
231 u_result SocketAddress::getAddressAsString(char * buffer, size_t buffersize) const
232 {
233  int net_family = reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family;
234  const char *ans = NULL;
235  switch (net_family) {
236  case AF_INET:
237  ans = _inet_ntop(net_family, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr,
238  buffer, buffersize);
239  break;
240 
241  case AF_INET6:
242  ans = _inet_ntop(net_family, &reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr,
243  buffer, buffersize);
244 
245  break;
246  }
247  return ans<=0?RESULT_OPERATION_FAIL:RESULT_OK;
248 }
249 
250 
251 
252 size_t SocketAddress::LoopUpHostName(const char * hostname, const char * sevicename, std::vector<SocketAddress> &addresspool , bool performDNS, SocketAddress::address_type_t type)
253 {
254  struct addrinfo hints;
255  struct addrinfo *result;
256  int ans;
258  memset(&hints, 0, sizeof(struct addrinfo));
259  hints.ai_family = _halAddrTypeToOSType(type);
260  hints.ai_flags = AI_PASSIVE;
261 
262  if (!performDNS) {
263  hints.ai_family |= AI_NUMERICSERV | AI_NUMERICHOST;
264 
265  }
266 
267  ans = getaddrinfo(hostname, sevicename, &hints, &result);
268 
269  addresspool.clear();
270 
271  if (ans != 0) {
272  // hostname loopup failed
273  return 0;
274  }
275 
276 
277  for (struct addrinfo * cursor = result; cursor != NULL; cursor = cursor->ai_next) {
278  if (cursor->ai_family == ADDRESS_TYPE_INET || cursor->ai_family == ADDRESS_TYPE_INET6) {
279  sockaddr_storage * storagebuffer = new sockaddr_storage;
280  assert(sizeof(sockaddr_storage) >= cursor->ai_addrlen);
281  memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
282  addresspool.push_back(SocketAddress(storagebuffer));
283  }
284  }
285 
286 
287  freeaddrinfo(result);
288 
289  return addresspool.size();
290 }
291 
292 
293 u_result SocketAddress::getRawAddress(_u8 * buffer, size_t bufferSize) const
294 {
295  switch (getAddressType()) {
296  case ADDRESS_TYPE_INET:
297  if (bufferSize < sizeof(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr)) return RESULT_INSUFFICIENT_MEMORY;
298 
299  memcpy(buffer, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr, sizeof(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr));
300 
301 
302  break;
303  case ADDRESS_TYPE_INET6:
304  if (bufferSize < sizeof(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr)) return RESULT_INSUFFICIENT_MEMORY;
305  memcpy(buffer, reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr, sizeof(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr));
306 
307  break;
308  default:
309  return RESULT_OPERATION_FAIL;
310  }
311  return RESULT_OK;
312 }
313 
314 
316 {
317 
318  int prevPort = getPort();
319  switch (type) {
320  case ADDRESS_TYPE_INET:
321  {
322  sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
323  addrv4->sin_family = AF_INET;
324  addrv4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
325  }
326  break;
327  case ADDRESS_TYPE_INET6:
328  {
329  sockaddr_in6 * addrv6 = reinterpret_cast<sockaddr_in6 *>(_platform_data);
330  addrv6->sin6_family = AF_INET6;
331  addrv6->sin6_addr = in6addr_loopback;
332 
333  }
334  break;
335  default:
336  return;
337  }
338 
339  setPort(prevPort);
340 }
341 
343 {
344 
345  int prevPort = getPort();
346  sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
347  addrv4->sin_family = AF_INET;
348  addrv4->sin_addr.s_addr = htonl(INADDR_BROADCAST);
349  setPort(prevPort);
350 
351 }
352 
354 {
355  int prevPort = getPort();
356  switch (type) {
357  case ADDRESS_TYPE_INET:
358  {
359  sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
360  addrv4->sin_family = AF_INET;
361  addrv4->sin_addr.s_addr = htonl(INADDR_ANY);
362  }
363  break;
364  case ADDRESS_TYPE_INET6:
365  {
366  sockaddr_in6 * addrv6 = reinterpret_cast<sockaddr_in6 *>(_platform_data);
367  addrv6->sin6_family = AF_INET6;
368  addrv6->sin6_addr = in6addr_any;
369 
370  }
371  break;
372  default:
373  return;
374  }
375 
376  setPort(prevPort);
377 
378 
379 }
380 
381 
382 }}
383 
384 
385 
387 
388 
389 namespace rp { namespace arch { namespace net{
390 
391 using namespace rp::net;
392 
393 class _single_thread StreamSocketImpl : public StreamSocket
394 {
395 public:
396 
397  StreamSocketImpl(SOCKET fd)
398  : _socket_fd(fd)
399  {
400  assert(fd>=0);
401  int bool_true = 1;
402  ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR , (char *)&bool_true, (int)sizeof(bool_true) );
403 
404  enableNoDelay(true);
405  this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
406  }
407 
408  virtual ~StreamSocketImpl()
409  {
410  closesocket(_socket_fd);
411  }
412 
413  virtual void dispose()
414  {
415  delete this;
416  }
417 
418 
419  virtual u_result bind(const SocketAddress & localaddr)
420  {
421  const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
422  assert(addr);
423  int ans = ::bind(_socket_fd, addr, (int)sizeof(sockaddr_storage));
424  if (ans) {
425  return RESULT_OPERATION_FAIL;
426  } else {
427  return RESULT_OK;
428  }
429  }
430 
432  {
433  struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData())); //donnot do this at home...
434  assert(addr);
435 
436  int actualsize = sizeof(sockaddr_storage);
437  int ans = ::getsockname(_socket_fd, addr, &actualsize);
438 
439  assert(actualsize <= sizeof(sockaddr_storage));
440  assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
441 
442  return ans?RESULT_OPERATION_FAIL:RESULT_OK;
443  }
444 
446  {
447  int ans;
448  timeval tv;
449  tv.tv_sec = timeout / 1000;
450  tv.tv_usec = (timeout % 1000) * 1000;
451 
452  if (msk & SOCKET_DIR_RD) {
453  ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, (int)sizeof(tv) );
454  if (ans) return RESULT_OPERATION_FAIL;
455  }
456 
457  if (msk & SOCKET_DIR_WR) {
458  ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, (int)sizeof(tv) );
459  if (ans) return RESULT_OPERATION_FAIL;
460  }
461 
462  return RESULT_OK;
463  }
464 
465  virtual u_result connect(const SocketAddress & pairAddress)
466  {
467  const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
468  int ans = ::connect(_socket_fd, addr, (int)sizeof(sockaddr_storage));
469  if (!ans) return RESULT_OK;
470 
471 
472  switch (WSAGetLastError()) {
473  case WSAEAFNOSUPPORT:
475 #if 0
476  case EINPROGRESS:
477  return RESULT_OK; //treat async connection as good status
478 #endif
479  case WSAETIMEDOUT:
481  default:
482  return RESULT_OPERATION_FAIL;
483  }
484  }
485 
486  virtual u_result listen(int backlog)
487  {
488  int ans = ::listen( _socket_fd, backlog);
489 
490  return ans?RESULT_OPERATION_FAIL:RESULT_OK;
491  }
492 
493  virtual StreamSocket * accept(SocketAddress * pairAddress)
494  {
495  int addrsize;
496  addrsize = sizeof(sockaddr_storage);
497  SOCKET pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
498  , &addrsize);
499 
500  if (pair_socket>=0) {
501  return new StreamSocketImpl(pair_socket);
502  } else {
503  return NULL;
504  }
505  }
506 
508  {
509  return waitforData(timeout);
510  }
511 
512  virtual u_result send(const void * buffer, size_t len)
513  {
514  int ans = ::send( _socket_fd, (const char *)buffer, len, 0);
515  if (ans != SOCKET_ERROR ) {
516  assert(ans == (int)len);
517 
518  return RESULT_OK;
519  } else {
520  switch(WSAGetLastError()) {
521  case WSAETIMEDOUT:
523  default:
524  return RESULT_OPERATION_FAIL;
525  }
526 
527  }
528 
529  }
530 
531  virtual u_result recv(void *buf, size_t len, size_t & recv_len)
532  {
533  int ans = ::recv( _socket_fd, (char *)buf, len, 0);
534  //::setsockopt(_socket_fd, IPPROTO_TCP, TCP_QUICKACK, (const char *)1, sizeof(int));
535  //::setsockopt(_socket_fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){1}, sizeof(int))
536  if (ans == SOCKET_ERROR) {
537  recv_len = 0;
538  switch(WSAGetLastError()) {
539  case WSAETIMEDOUT:
541  default:
542  return RESULT_OPERATION_FAIL;
543  }
544  } else {
545  recv_len = ans;
546  return RESULT_OK;
547  }
548  }
549 
551  {
552  struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData())); //donnot do this at home...
553  assert(addr);
554  int actualsize = (int)sizeof(sockaddr_storage);
555  int ans = ::getpeername(_socket_fd, addr, &actualsize);
556 
557  assert(actualsize <= (int)sizeof(sockaddr_storage));
558  assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
559 
560  return ans?RESULT_OPERATION_FAIL:RESULT_OK;
561 
562  }
563 
565  {
566  int shutdw_opt ;
567 
568  switch (mask) {
569  case SOCKET_DIR_RD:
570  shutdw_opt = SD_RECEIVE;
571  break;
572  case SOCKET_DIR_WR:
573  shutdw_opt = SD_SEND;
574  break;
575  case SOCKET_DIR_BOTH:
576  default:
577  shutdw_opt = SD_BOTH;
578  }
579 
580  int ans = ::shutdown(_socket_fd, shutdw_opt);
581  return ans?RESULT_OPERATION_FAIL:RESULT_OK;
582  }
583 
584  virtual u_result enableKeepAlive(bool enable)
585  {
586  int bool_true = enable?1:0;
587  return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , (const char *)&bool_true, (int)sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
588  }
589 
590  virtual u_result enableNoDelay(bool enable )
591  {
592  int bool_true = enable?1:0;
593  return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&bool_true, (int)sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
594  }
595 
596  virtual u_result waitforSent(_u32 timeout )
597  {
598  fd_set wrset;
599  FD_ZERO(&wrset);
600  FD_SET(_socket_fd, &wrset);
601 
602  timeval tv;
603  tv.tv_sec = timeout / 1000;
604  tv.tv_usec = (timeout % 1000) * 1000;
605  int ans = ::select(NULL, NULL, &wrset, NULL, &tv);
606 
607  switch (ans) {
608  case 1:
609  // fired
610  return RESULT_OK;
611  case 0:
612  // timeout
614  default:
615  delay(0); //relax cpu
616  return RESULT_OPERATION_FAIL;
617  }
618  }
619 
620  virtual u_result waitforData(_u32 timeout )
621  {
622  fd_set rdset;
623  FD_ZERO(&rdset);
624  FD_SET(_socket_fd, &rdset);
625 
626  timeval tv;
627  tv.tv_sec = timeout / 1000;
628  tv.tv_usec = (timeout % 1000) * 1000;
629  int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
630 
631  switch (ans) {
632  case 1:
633  // fired
634  return RESULT_OK;
635  case 0:
636  // timeout
638  default:
639  delay(0); //relax cpu
640  return RESULT_OPERATION_FAIL;
641  }
642  }
643 
644 protected:
645 
646  SOCKET _socket_fd;
647 
648 
649 };
650 
651 
653 {
654 public:
655 
656  DGramSocketImpl(SOCKET fd)
657  : _socket_fd(fd)
658  {
659  assert(fd>=0);
660  int bool_true = 1;
661  ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, (int)sizeof(bool_true) );
662  setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
663  }
664 
665  virtual ~DGramSocketImpl()
666  {
667  closesocket(_socket_fd);
668  }
669 
670  virtual void dispose()
671  {
672  delete this;
673  }
674 
675 
676  virtual u_result bind(const SocketAddress & localaddr)
677  {
678  const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
679  assert(addr);
680  int ans = ::bind(_socket_fd, addr, (int)sizeof(sockaddr_storage));
681  if (ans) {
682  return RESULT_OPERATION_FAIL;
683  } else {
684  return RESULT_OK;
685  }
686  }
687 
689  {
690  struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData()))); //donnot do this at home...
691  assert(addr);
692 
693  int actualsize = (int)sizeof(sockaddr_storage);
694  int ans = ::getsockname(_socket_fd, addr, &actualsize);
695 
696  assert(actualsize <= (int)sizeof(sockaddr_storage));
697  assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
698 
699  return ans?RESULT_OPERATION_FAIL:RESULT_OK;
700  }
701 
703  {
704  int ans;
705  timeval tv;
706  tv.tv_sec = timeout / 1000;
707  tv.tv_usec = (timeout % 1000) * 1000;
708 
709  if (msk & SOCKET_DIR_RD) {
710  ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, (int)sizeof(tv) );
711  if (ans) return RESULT_OPERATION_FAIL;
712  }
713 
714  if (msk & SOCKET_DIR_WR) {
715  ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, (int)sizeof(tv) );
716  if (ans) return RESULT_OPERATION_FAIL;
717  }
718 
719  return RESULT_OK;
720  }
721 
722 
723  virtual u_result waitforSent(_u32 timeout )
724  {
725  fd_set wrset;
726  FD_ZERO(&wrset);
727  FD_SET(_socket_fd, &wrset);
728 
729  timeval tv;
730  tv.tv_sec = timeout / 1000;
731  tv.tv_usec = (timeout % 1000) * 1000;
732  int ans = ::select(NULL, NULL, &wrset, NULL, &tv);
733 
734  switch (ans) {
735  case 1:
736  // fired
737  return RESULT_OK;
738  case 0:
739  // timeout
741  default:
742  delay(0); //relax cpu
743  return RESULT_OPERATION_FAIL;
744  }
745  }
746 
747  virtual u_result waitforData(_u32 timeout )
748  {
749  fd_set rdset;
750  FD_ZERO(&rdset);
751  FD_SET(_socket_fd, &rdset);
752 
753  timeval tv;
754  tv.tv_sec = timeout / 1000;
755  tv.tv_usec = (timeout % 1000) * 1000;
756  int ans = ::select(NULL, &rdset, NULL, NULL, &tv);
757 
758  switch (ans) {
759  case 1:
760  // fired
761  return RESULT_OK;
762  case 0:
763  // timeout
765  default:
766  delay(0); //relax cpu
767  return RESULT_OPERATION_FAIL;
768  }
769  }
770 
771  virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
772  {
773  const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
774  assert(addr);
775  int ans = ::sendto( _socket_fd, (const char *)buffer, (int)len, 0, addr, (int)sizeof(sockaddr_storage));
776  if (ans != SOCKET_ERROR) {
777  assert(ans == (int)len);
778  return RESULT_OK;
779  } else {
780  switch(WSAGetLastError()) {
781  case WSAETIMEDOUT:
783  case WSAEMSGSIZE:
784  return RESULT_INVALID_DATA;
785  default:
786  return RESULT_OPERATION_FAIL;
787  }
788  }
789 
790  }
791 
792 
793  virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
794  {
795  struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
796  int source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
797 
798  int ans = ::recvfrom( _socket_fd, (char *)buf, (int)len, 0, addr, addr?&source_addr_size:NULL);
799  if (ans == SOCKET_ERROR) {
800  recv_len = 0;
801  int errCode = WSAGetLastError();
802  switch(errCode) {
803  case WSAETIMEDOUT:
805  default:
806  return RESULT_OPERATION_FAIL;
807  }
808  } else {
809  recv_len = ans;
810  return RESULT_OK;
811  }
812 
813  }
814 
815 
816 
817 protected:
818  SOCKET _socket_fd;
819 
820 };
821 
822 
823 }}}
824 
825 
826 namespace rp { namespace net{
827 
828 
829 
831 {
832  switch (family) {
834  return AF_INET;
836  return AF_INET6;
838  return AF_UNSPEC; //win32 doesn't support RAW Packet
839  default:
840  assert(!"should not reach here");
841  return AF_INET; // force treating as IPv4 in release mode
842  }
843 
844 }
845 
847 {
849  if (family == SOCKET_FAMILY_RAW) return NULL;
850 
851 
852  int socket_family = _socketHalFamilyToOSFamily(family);
853  int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
854  if (socket_fd == -1) return NULL;
855  StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
856  return newborn;
857 
858 }
859 
860 
862 {
864  int socket_family = _socketHalFamilyToOSFamily(family);
865 
866 
867  int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
868  if (socket_fd == -1) return NULL;
869  DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
870  return newborn;
871 
872 }
873 
874 
875 }}
876 
virtual StreamSocket * accept(SocketAddress *pairAddress)
static const char * _inet_ntop(int af, const void *src, char *dst, int cnt)
static int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
static volatile bool _isWSAStartupCalled
virtual void setAnyAddress(address_type_t=ADDRESS_TYPE_INET)
virtual u_result setPort(int port)
virtual void setLoopbackAddress(address_type_t=ADDRESS_TYPE_INET)
virtual u_result connect(const SocketAddress &pairAddress)
virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
static int _halAddrTypeToOSType(SocketAddress::address_type_t type)
_u32 result
Definition: rplidar_cmd.h:2
virtual void setBroadcastAddressIPv4()
#define RESULT_OK
Definition: rptypes.h:102
virtual u_result recvFrom(void *buf, size_t len, size_t &recv_len, SocketAddress *sourceAddr)
SocketAddress & operator=(const SocketAddress &)
virtual u_result recv(void *buf, size_t len, size_t &recv_len)
virtual u_result getAddressAsString(char *buffer, size_t buffersize) const
virtual u_result waitforData(_u32 timeout)
#define RESULT_INSUFFICIENT_MEMORY
Definition: rptypes.h:111
static size_t LoopUpHostName(const char *hostname, const char *sevicename, std::vector< SocketAddress > &addresspool, bool performDNS=true, address_type_t=ADDRESS_TYPE_INET)
virtual u_result enableKeepAlive(bool enable)
virtual u_result waitforSent(_u32 timeout)
#define delay(x)
Definition: win32/timer.h:39
static int _inet_pton(int Family, const char *pszAddrString, void *pAddrBuf)
uint8_t _u8
Definition: rptypes.h:63
virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
virtual u_result setAddressFromString(const char *address_string, address_type_t=ADDRESS_TYPE_INET)
const void * getPlatformData() const
Definition: socket.h:47
#define _single_thread
Definition: types.h:84
virtual u_result waitforSent(_u32 timeout)
void * _platform_data
Definition: socket.h:59
virtual u_result sendTo(const SocketAddress &target, const void *buffer, size_t len)
virtual u_result getLocalAddress(SocketAddress &localaddr)
virtual u_result listen(int backlog)
virtual u_result bind(const SocketAddress &localaddr)
static bool _checkWSAStartup()
static StreamSocket * CreateSocket(socket_family_t family=SOCKET_FAMILY_INET)
#define RESULT_OPERATION_TIMEOUT
Definition: rptypes.h:107
virtual u_result getLocalAddress(SocketAddress &localaddr)
virtual u_result send(const void *buffer, size_t len)
virtual u_result waitforData(_u32 timeout)
virtual address_type_t getAddressType() const
virtual u_result enableNoDelay(bool enable)
_u32 type
Definition: rplidar_cmd.h:2
virtual u_result getPeerAddress(SocketAddress &peerAddr)
virtual u_result shutdown(socket_direction_mask mask)
uint32_t _u32
Definition: rptypes.h:69
#define RESULT_OPERATION_NOT_SUPPORT
Definition: rptypes.h:109
virtual u_result bind(const SocketAddress &localaddr)
#define RESULT_OPERATION_FAIL
Definition: rptypes.h:106
virtual u_result getRawAddress(_u8 *buffer, size_t bufferSize) const
virtual int getPort() const
#define RESULT_INVALID_DATA
Definition: rptypes.h:105
static DGramSocket * CreateSocket(socket_family_t family=SOCKET_FAMILY_INET)
uint32_t u_result
Definition: rptypes.h:100
virtual u_result waitforIncomingConnection(_u32 timeout)


rplidar_ros
Author(s):
autogenerated on Wed Mar 20 2019 07:54:15