net_socket.cpp
Go to the documentation of this file.
00001 /*
00002  *  RoboPeak Project
00003  *  HAL Layer - Socket Interface
00004  *  Copyright 2009 - 2013 RoboPeak Project
00005  *
00006  *  Win32 Implementation
00007  */
00008 
00009 #define _WINSOCKAPI_
00010 
00011 #include "sdkcommon.h"
00012 #include "..\..\hal\socket.h"
00013 #include <windows.h>  
00014 #include <winsock2.h>
00015 #include <ws2tcpip.h>
00016 
00017 #include <stdlib.h>  
00018 #include <stdio.h>  
00019 #pragma comment (lib, "Ws2_32.lib")
00020 
00021 namespace rp{ namespace net {
00022 
00023 static volatile bool _isWSAStartupCalled = false;
00024 
00025 static inline bool _checkWSAStartup() {
00026     int  iResult;
00027     WSADATA wsaData;
00028     if (!_isWSAStartupCalled) {
00029         iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
00030         if (iResult != 0) {
00031             return false;
00032         }
00033         _isWSAStartupCalled = true;
00034     }
00035     return true;
00036 }
00037 
00038 static const char* _inet_ntop(int af, const void* src, char* dst, int cnt){
00039 
00040         struct sockaddr_storage srcaddr;
00041 
00042 
00043     memset(dst, 0, cnt);
00044 
00045         memset(&srcaddr, 0, sizeof(struct sockaddr_storage));
00046         
00047 
00048     srcaddr.ss_family = af;
00049 
00050     switch (af) {
00051     case AF_INET:
00052         {
00053             struct sockaddr_in * ipv4 = reinterpret_cast< struct sockaddr_in *>(&srcaddr);
00054             memcpy(&(ipv4->sin_addr), src, sizeof(ipv4->sin_addr));
00055         }
00056         break;
00057     case AF_INET6:
00058         {
00059             struct sockaddr_in6 * ipv6 = reinterpret_cast< struct sockaddr_in6 *>(&srcaddr);
00060             memcpy(&(ipv6->sin6_addr), src, sizeof(ipv6->sin6_addr));
00061         }
00062         break;
00063     }
00064 
00065         if (WSAAddressToStringA((struct sockaddr*) &srcaddr, sizeof(struct sockaddr_storage), 0, dst, (LPDWORD) &cnt) != 0) {
00066                 DWORD rv = WSAGetLastError();
00067                 return NULL;
00068         }
00069         return dst;
00070 }
00071 
00072 static int _inet_pton(int Family, const char * pszAddrString, void* pAddrBuf)
00073 {
00074     struct sockaddr_storage tmpholder;
00075     int actualSize =  sizeof(sockaddr_storage);
00076 
00077     int result = WSAStringToAddressA((char *)pszAddrString, Family, NULL, (sockaddr*)&tmpholder, &actualSize);
00078     if (result) return -1;
00079 
00080     switch (Family) {
00081         case AF_INET:
00082             {
00083                 struct sockaddr_in * ipv4 = reinterpret_cast< struct sockaddr_in *>(&tmpholder);
00084                 memcpy(pAddrBuf, &(ipv4->sin_addr), sizeof(ipv4->sin_addr));
00085             }
00086             break;
00087         case AF_INET6:
00088             {
00089                 struct sockaddr_in6 * ipv6 = reinterpret_cast< struct sockaddr_in6 *>(&tmpholder);
00090                 memcpy(pAddrBuf, &(ipv6->sin6_addr), sizeof(ipv6->sin6_addr));
00091             }
00092             break;
00093     }
00094     return 1;
00095 }
00096 
00097 static inline int _halAddrTypeToOSType(SocketAddress::address_type_t type) 
00098 {
00099     switch (type) {
00100         case SocketAddress::ADDRESS_TYPE_INET:
00101             return AF_INET;
00102         case SocketAddress::ADDRESS_TYPE_INET6:
00103             return AF_INET6;
00104         case SocketAddress::ADDRESS_TYPE_UNSPEC:
00105             return AF_UNSPEC;
00106 
00107         default:
00108             assert(!"should not reach here");
00109             return AF_UNSPEC;
00110     }
00111 }
00112 
00113 
00114 SocketAddress::SocketAddress() 
00115 {
00116     _checkWSAStartup();
00117     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00118     memset(_platform_data, 0, sizeof(sockaddr_storage));
00119     
00120     reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00121 }
00122 
00123 SocketAddress::SocketAddress(const SocketAddress & src)
00124 {
00125     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00126     memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00127 }
00128 
00129 
00130 
00131 SocketAddress::SocketAddress(const char * addrString, int port, SocketAddress::address_type_t type)
00132 {
00133     _checkWSAStartup();
00134     _platform_data = reinterpret_cast<void *>(new sockaddr_storage);
00135     memset(_platform_data, 0, sizeof(sockaddr_storage));
00136     
00137     // default to ipv4 in case the following operation fails
00138     reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00139 
00140     setAddressFromString(addrString, type);
00141     setPort(port);
00142 }
00143 
00144 SocketAddress::SocketAddress(void * platform_data)
00145  : _platform_data(platform_data)
00146 { _checkWSAStartup(); }
00147 
00148 SocketAddress & SocketAddress::operator = (const SocketAddress &src)
00149 {
00150     memcpy(_platform_data, src._platform_data, sizeof(sockaddr_storage));
00151     return *this;
00152 }
00153 
00154 
00155 SocketAddress::~SocketAddress()
00156 {
00157     delete reinterpret_cast<sockaddr_storage *>(_platform_data);
00158 }
00159 
00160 SocketAddress::address_type_t SocketAddress::getAddressType() const
00161 {
00162     switch(reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family) {
00163         case AF_INET:
00164             return ADDRESS_TYPE_INET;
00165         case AF_INET6:
00166             return ADDRESS_TYPE_INET6;
00167         default:
00168             assert(!"should not reach here");
00169             return ADDRESS_TYPE_INET;
00170     }
00171 }
00172 
00173 int SocketAddress::getPort() const
00174 {
00175     switch (getAddressType()) {
00176         case ADDRESS_TYPE_INET:
00177             return (int)ntohs(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_port);
00178         case ADDRESS_TYPE_INET6:
00179             return (int)ntohs(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_port);
00180         default:
00181             return 0;
00182     }
00183 }
00184 
00185 u_result SocketAddress::setPort(int port)
00186 {
00187     switch (getAddressType()) {
00188         case ADDRESS_TYPE_INET:
00189             reinterpret_cast<sockaddr_in *>(_platform_data)->sin_port = htons((short)port);
00190             break;
00191         case ADDRESS_TYPE_INET6:
00192             reinterpret_cast<sockaddr_in6 *>(_platform_data)->sin6_port = htons((short)port);
00193             break;
00194         default:
00195             return RESULT_OPERATION_FAIL;
00196     }
00197     return RESULT_OK;
00198 }
00199 
00200 u_result SocketAddress::setAddressFromString(const char * address_string,  SocketAddress::address_type_t type)
00201 {
00202     int ans = 0;
00203     int prevPort = getPort();
00204     switch (type) {
00205         case ADDRESS_TYPE_INET:
00206             reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET;
00207             ans = _inet_pton(AF_INET, 
00208                             address_string, 
00209                             &reinterpret_cast<sockaddr_in *>(_platform_data)->sin_addr);
00210         break;
00211 
00212 
00213         case ADDRESS_TYPE_INET6:
00214             
00215             reinterpret_cast<sockaddr_storage *>(_platform_data)->ss_family = AF_INET6;
00216             ans = _inet_pton(AF_INET6, 
00217                             address_string, 
00218                             &reinterpret_cast<sockaddr_in6  *>(_platform_data)->sin6_addr);
00219         break;
00220 
00221         default:
00222             return RESULT_INVALID_DATA;
00223 
00224     }
00225     setPort(prevPort);
00226 
00227     return ans<=0?RESULT_INVALID_DATA:RESULT_OK;
00228 }
00229 
00230 
00231 u_result SocketAddress::getAddressAsString(char * buffer, size_t buffersize) const
00232 {
00233     int net_family = reinterpret_cast<const sockaddr_storage *>(_platform_data)->ss_family;
00234     const char *ans = NULL;
00235     switch (net_family) {
00236         case AF_INET:
00237             ans = _inet_ntop(net_family, &reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr,
00238                             buffer, buffersize);
00239         break;
00240 
00241         case AF_INET6:
00242             ans = _inet_ntop(net_family, &reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr,
00243                             buffer, buffersize);
00244 
00245         break;
00246     }
00247     return ans<=0?RESULT_OPERATION_FAIL:RESULT_OK;
00248 }
00249 
00250 
00251 
00252 size_t SocketAddress::LoopUpHostName(const char * hostname, const char * sevicename, std::vector<SocketAddress> &addresspool , bool performDNS, SocketAddress::address_type_t type)
00253 {
00254     struct addrinfo hints;
00255     struct addrinfo *result;
00256     int ans;
00257     _checkWSAStartup();
00258     memset(&hints, 0, sizeof(struct addrinfo));
00259     hints.ai_family = _halAddrTypeToOSType(type);
00260     hints.ai_flags = AI_PASSIVE;
00261 
00262     if (!performDNS) {
00263         hints.ai_family |= AI_NUMERICSERV | AI_NUMERICHOST;
00264     
00265     }
00266 
00267     ans = getaddrinfo(hostname, sevicename, &hints, &result);
00268 
00269     addresspool.clear();
00270 
00271     if (ans != 0) {
00272         // hostname loopup failed
00273         return 0;
00274     }
00275 
00276     
00277     for (struct addrinfo * cursor = result; cursor != NULL; cursor = cursor->ai_next) {
00278         if (cursor->ai_family == ADDRESS_TYPE_INET || cursor->ai_family == ADDRESS_TYPE_INET6) {
00279             sockaddr_storage * storagebuffer = new sockaddr_storage;
00280             assert(sizeof(sockaddr_storage) >= cursor->ai_addrlen);
00281             memcpy(storagebuffer, cursor->ai_addr, cursor->ai_addrlen);
00282             addresspool.push_back(SocketAddress(storagebuffer));
00283         }
00284     }
00285 
00286     
00287     freeaddrinfo(result);
00288 
00289     return addresspool.size();
00290 }
00291 
00292 
00293 u_result SocketAddress::getRawAddress(_u8 * buffer, size_t bufferSize) const
00294 {
00295      switch (getAddressType()) {
00296         case ADDRESS_TYPE_INET:
00297             if (bufferSize < sizeof(reinterpret_cast<const sockaddr_in *>(_platform_data)->sin_addr.s_addr)) return RESULT_INSUFFICIENT_MEMORY;
00298 
00299             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));
00300 
00301             
00302             break;
00303         case ADDRESS_TYPE_INET6:
00304             if (bufferSize < sizeof(reinterpret_cast<const sockaddr_in6 *>(_platform_data)->sin6_addr.s6_addr)) return RESULT_INSUFFICIENT_MEMORY;
00305             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));
00306 
00307             break;
00308         default:
00309             return RESULT_OPERATION_FAIL;
00310     }
00311     return RESULT_OK;
00312 }
00313 
00314 
00315 void SocketAddress::setLoopbackAddress(SocketAddress::address_type_t type)
00316 {
00317 
00318     int prevPort = getPort();
00319     switch (type) {
00320         case ADDRESS_TYPE_INET:
00321             {
00322                 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00323                 addrv4->sin_family = AF_INET;
00324                 addrv4->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00325             }
00326             break;
00327         case ADDRESS_TYPE_INET6:
00328             {
00329                 sockaddr_in6  * addrv6 = reinterpret_cast<sockaddr_in6  *>(_platform_data);
00330                 addrv6->sin6_family = AF_INET6;
00331                 addrv6->sin6_addr = in6addr_loopback;
00332 
00333             }
00334             break;
00335         default:
00336             return;
00337     }
00338 
00339     setPort(prevPort);
00340 }
00341 
00342 void SocketAddress::setBroadcastAddressIPv4()
00343 {
00344 
00345     int prevPort = getPort();
00346     sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00347     addrv4->sin_family = AF_INET;
00348     addrv4->sin_addr.s_addr = htonl(INADDR_BROADCAST);
00349     setPort(prevPort);
00350 
00351 }
00352 
00353 void SocketAddress::setAnyAddress(SocketAddress::address_type_t type)
00354 {
00355     int prevPort = getPort();
00356     switch (type) {
00357         case ADDRESS_TYPE_INET:
00358             {
00359                 sockaddr_in * addrv4 = reinterpret_cast<sockaddr_in *>(_platform_data);
00360                 addrv4->sin_family = AF_INET;
00361                 addrv4->sin_addr.s_addr = htonl(INADDR_ANY);
00362             }
00363             break;
00364         case ADDRESS_TYPE_INET6:
00365             {
00366                 sockaddr_in6  * addrv6 = reinterpret_cast<sockaddr_in6  *>(_platform_data);
00367                 addrv6->sin6_family = AF_INET6;
00368                 addrv6->sin6_addr = in6addr_any;
00369 
00370             }
00371             break;
00372         default:
00373             return;
00374     }
00375 
00376     setPort(prevPort);
00377 
00378 
00379 }
00380 
00381 
00382 }}
00383 
00384 
00385 
00387 
00388 
00389 namespace rp { namespace arch { namespace net{ 
00390 
00391 using namespace rp::net;
00392 
00393 class _single_thread StreamSocketImpl : public StreamSocket
00394 {
00395 public:
00396 
00397     StreamSocketImpl(SOCKET fd)
00398         : _socket_fd(fd)
00399     {
00400         assert(fd>=0);
00401         int bool_true = 1;
00402         ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR , (char *)&bool_true, (int)sizeof(bool_true) );
00403         
00404         enableNoDelay(true);
00405         this->setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00406     }
00407 
00408     virtual ~StreamSocketImpl() 
00409     {
00410         closesocket(_socket_fd);
00411     }
00412 
00413     virtual void dispose()
00414     {
00415         delete this;
00416     }
00417 
00418 
00419     virtual u_result bind(const SocketAddress & localaddr)
00420     {
00421         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00422         assert(addr);
00423         int ans = ::bind(_socket_fd, addr, (int)sizeof(sockaddr_storage));
00424         if (ans) {
00425             return RESULT_OPERATION_FAIL;
00426         } else {
00427             return RESULT_OK;
00428         }
00429     }
00430 
00431     virtual u_result getLocalAddress(SocketAddress & localaddr)
00432     {
00433         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>( const_cast<void *>(localaddr.getPlatformData())); //donnot do this at home...
00434         assert(addr);
00435 
00436         int actualsize =  sizeof(sockaddr_storage);
00437         int ans = ::getsockname(_socket_fd, addr, &actualsize);
00438 
00439         assert(actualsize <= sizeof(sockaddr_storage));
00440         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00441 
00442         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00443     }
00444 
00445     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00446     {
00447         int ans;
00448         timeval tv;
00449         tv.tv_sec = timeout / 1000; 
00450         tv.tv_usec = (timeout % 1000) * 1000; 
00451 
00452         if (msk & SOCKET_DIR_RD) {
00453              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, (int)sizeof(tv) );
00454              if (ans) return RESULT_OPERATION_FAIL;
00455         }
00456 
00457         if (msk & SOCKET_DIR_WR) {
00458              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, (int)sizeof(tv) );
00459              if (ans) return RESULT_OPERATION_FAIL;
00460         }
00461 
00462         return RESULT_OK;
00463     }
00464   
00465     virtual u_result connect(const SocketAddress & pairAddress)
00466     {
00467         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(pairAddress.getPlatformData());
00468         int ans = ::connect(_socket_fd, addr, (int)sizeof(sockaddr_storage));
00469         if (!ans) return RESULT_OK;
00470 
00471 
00472         switch (WSAGetLastError()) {
00473             case WSAEAFNOSUPPORT:
00474                 return RESULT_OPERATION_NOT_SUPPORT;
00475 #if 0
00476             case EINPROGRESS:
00477                 return RESULT_OK; //treat async connection as good status
00478 #endif
00479             case WSAETIMEDOUT:
00480                 return RESULT_OPERATION_TIMEOUT;
00481             default:
00482                 return RESULT_OPERATION_FAIL;
00483         }
00484     }
00485       
00486     virtual u_result listen(int backlog)
00487     {
00488         int ans = ::listen( _socket_fd,   backlog);
00489 
00490         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00491     }
00492 
00493     virtual StreamSocket * accept(SocketAddress * pairAddress) 
00494     {
00495         int addrsize;
00496         addrsize = sizeof(sockaddr_storage);
00497         SOCKET pair_socket = ::accept( _socket_fd, pairAddress?reinterpret_cast<struct sockaddr *>(const_cast<void *>(pairAddress->getPlatformData())):NULL
00498             , &addrsize);
00499 
00500         if (pair_socket>=0) {
00501             return new StreamSocketImpl(pair_socket);
00502         } else {
00503             return NULL;
00504         }
00505     }
00506 
00507     virtual u_result waitforIncomingConnection(_u32 timeout)
00508     {
00509         return waitforData(timeout);
00510     }
00511 
00512     virtual u_result send(const void * buffer, size_t len) 
00513     {
00514         int ans = ::send( _socket_fd, (const char *)buffer, len, 0);
00515         if (ans != SOCKET_ERROR ) {
00516             assert(ans == (int)len);
00517 
00518             return RESULT_OK;
00519         } else {
00520             switch(WSAGetLastError()) {
00521             case WSAETIMEDOUT:
00522                 return RESULT_OPERATION_TIMEOUT;
00523             default:
00524                 return RESULT_OPERATION_FAIL;
00525             }
00526             
00527         }
00528         
00529     }
00530 
00531     virtual u_result recv(void *buf, size_t len, size_t & recv_len)
00532     {
00533         int ans = ::recv( _socket_fd, (char *)buf, len, 0);
00534                 //::setsockopt(_socket_fd, IPPROTO_TCP, TCP_QUICKACK,  (const char *)1, sizeof(int));
00535                 //::setsockopt(_socket_fd, IPPROTO_TCP, TCP_QUICKACK, (int[]){1}, sizeof(int))
00536         if (ans == SOCKET_ERROR) {
00537             recv_len = 0;  
00538                 switch(WSAGetLastError()) {
00539                 case WSAETIMEDOUT:
00540                     return RESULT_OPERATION_TIMEOUT;
00541                 default:
00542                     return RESULT_OPERATION_FAIL;
00543                 }
00544         } else {
00545             recv_len = ans;
00546             return RESULT_OK;
00547         }
00548     }
00549 
00550     virtual u_result getPeerAddress(SocketAddress & peerAddr)
00551     {
00552         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>(peerAddr.getPlatformData())); //donnot do this at home...
00553         assert(addr);
00554         int actualsize =  (int)sizeof(sockaddr_storage);
00555         int ans = ::getpeername(_socket_fd, addr, &actualsize);
00556 
00557         assert(actualsize <=  (int)sizeof(sockaddr_storage));
00558         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00559 
00560         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00561 
00562     }
00563 
00564     virtual u_result shutdown(socket_direction_mask mask)
00565     {
00566         int shutdw_opt ;
00567 
00568         switch (mask) {
00569             case SOCKET_DIR_RD:
00570                 shutdw_opt = SD_RECEIVE;
00571                 break;
00572             case SOCKET_DIR_WR:
00573                 shutdw_opt = SD_SEND;
00574                 break;
00575             case SOCKET_DIR_BOTH:
00576             default:
00577                 shutdw_opt = SD_BOTH;
00578         }
00579 
00580         int ans = ::shutdown(_socket_fd, shutdw_opt);
00581         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00582     }
00583 
00584     virtual u_result enableKeepAlive(bool enable)
00585     {
00586         int bool_true = enable?1:0;
00587         return ::setsockopt( _socket_fd, SOL_SOCKET, SO_KEEPALIVE , (const char *)&bool_true, (int)sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00588     }
00589 
00590     virtual u_result enableNoDelay(bool enable ) 
00591     {
00592         int bool_true = enable?1:0;
00593         return ::setsockopt( _socket_fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&bool_true, (int)sizeof(bool_true) )?RESULT_OPERATION_FAIL:RESULT_OK;
00594     }
00595 
00596     virtual u_result waitforSent(_u32 timeout ) 
00597     {
00598         fd_set wrset;
00599         FD_ZERO(&wrset);
00600         FD_SET(_socket_fd, &wrset);
00601 
00602         timeval tv;
00603         tv.tv_sec = timeout / 1000;
00604         tv.tv_usec = (timeout % 1000) * 1000;
00605         int ans = ::select(NULL, NULL, &wrset, NULL, &tv);
00606 
00607         switch (ans) {
00608             case 1:
00609                 // fired
00610                 return RESULT_OK;
00611             case 0:
00612                 // timeout
00613                 return RESULT_OPERATION_TIMEOUT;
00614             default:
00615                 delay(0); //relax cpu
00616                 return RESULT_OPERATION_FAIL;
00617         }
00618     }
00619 
00620     virtual u_result waitforData(_u32 timeout )
00621     {
00622         fd_set rdset;
00623         FD_ZERO(&rdset);
00624         FD_SET(_socket_fd, &rdset);
00625 
00626         timeval tv;
00627         tv.tv_sec = timeout / 1000;
00628         tv.tv_usec = (timeout % 1000) * 1000;
00629         int ans = ::select(_socket_fd+1, &rdset, NULL, NULL, &tv);
00630 
00631         switch (ans) {
00632             case 1:
00633                 // fired
00634                 return RESULT_OK;
00635             case 0:
00636                 // timeout
00637                 return RESULT_OPERATION_TIMEOUT;
00638             default:
00639                 delay(0); //relax cpu
00640                 return RESULT_OPERATION_FAIL;
00641         }
00642     }
00643 
00644 protected:
00645 
00646     SOCKET  _socket_fd;
00647 
00648 
00649 };
00650 
00651 
00652 class _single_thread DGramSocketImpl : public DGramSocket
00653 {
00654 public:
00655 
00656     DGramSocketImpl(SOCKET fd)
00657         : _socket_fd(fd)
00658     {
00659         assert(fd>=0);
00660         int bool_true = 1;
00661         ::setsockopt( _socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_BROADCAST , (char *)&bool_true, (int)sizeof(bool_true) );
00662         setTimeout(DEFAULT_SOCKET_TIMEOUT, SOCKET_DIR_BOTH);
00663     }
00664 
00665     virtual ~DGramSocketImpl() 
00666     {
00667         closesocket(_socket_fd);
00668     }
00669 
00670     virtual void dispose()
00671     {
00672         delete this;
00673     }
00674 
00675 
00676     virtual u_result bind(const SocketAddress & localaddr)
00677     {
00678         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(localaddr.getPlatformData());
00679         assert(addr);
00680         int ans = ::bind(_socket_fd, addr, (int)sizeof(sockaddr_storage));
00681         if (ans) {
00682             return RESULT_OPERATION_FAIL;
00683         } else {
00684             return RESULT_OK;
00685         }
00686     }
00687 
00688     virtual u_result getLocalAddress(SocketAddress & localaddr)
00689     {
00690         struct sockaddr * addr = reinterpret_cast<struct sockaddr *>(const_cast<void *>((localaddr.getPlatformData()))); //donnot do this at home...
00691         assert(addr);
00692 
00693         int actualsize =  (int)sizeof(sockaddr_storage);
00694         int ans = ::getsockname(_socket_fd, addr, &actualsize);
00695 
00696         assert(actualsize <= (int)sizeof(sockaddr_storage));
00697         assert(addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
00698 
00699         return ans?RESULT_OPERATION_FAIL:RESULT_OK;
00700     }
00701 
00702     virtual u_result setTimeout(_u32 timeout, socket_direction_mask msk)
00703     {
00704         int ans;
00705         timeval tv;
00706         tv.tv_sec = timeout / 1000; 
00707         tv.tv_usec = (timeout % 1000) * 1000; 
00708 
00709         if (msk & SOCKET_DIR_RD) {
00710              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, (int)sizeof(tv) );
00711              if (ans) return RESULT_OPERATION_FAIL;
00712         }
00713 
00714         if (msk & SOCKET_DIR_WR) {
00715              ans = ::setsockopt( _socket_fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, (int)sizeof(tv) );
00716              if (ans) return RESULT_OPERATION_FAIL;
00717         }
00718 
00719         return RESULT_OK;
00720     }
00721   
00722 
00723     virtual u_result waitforSent(_u32 timeout ) 
00724     {
00725         fd_set wrset;
00726         FD_ZERO(&wrset);
00727         FD_SET(_socket_fd, &wrset);
00728 
00729         timeval tv;
00730         tv.tv_sec = timeout / 1000;
00731         tv.tv_usec = (timeout % 1000) * 1000;
00732         int ans = ::select(NULL, NULL, &wrset, NULL, &tv);
00733 
00734         switch (ans) {
00735             case 1:
00736                 // fired
00737                 return RESULT_OK;
00738             case 0:
00739                 // timeout
00740                 return RESULT_OPERATION_TIMEOUT;
00741             default:
00742                 delay(0); //relax cpu
00743                 return RESULT_OPERATION_FAIL;
00744         }
00745     }
00746 
00747     virtual u_result waitforData(_u32 timeout )
00748     {
00749         fd_set rdset;
00750         FD_ZERO(&rdset);
00751         FD_SET(_socket_fd, &rdset);
00752 
00753         timeval tv;
00754         tv.tv_sec = timeout / 1000;
00755         tv.tv_usec = (timeout % 1000) * 1000;
00756         int ans = ::select(NULL, &rdset, NULL, NULL, &tv);
00757 
00758         switch (ans) {
00759             case 1:
00760                 // fired
00761                 return RESULT_OK;
00762             case 0:
00763                 // timeout
00764                 return RESULT_OPERATION_TIMEOUT;
00765             default:
00766                 delay(0); //relax cpu
00767                 return RESULT_OPERATION_FAIL;
00768         }
00769     }
00770 
00771     virtual u_result sendTo(const SocketAddress & target, const void * buffer, size_t len)
00772     {
00773         const struct sockaddr * addr = reinterpret_cast<const struct sockaddr *>(target.getPlatformData());
00774         assert(addr);
00775         int ans = ::sendto( _socket_fd, (const char *)buffer, (int)len, 0, addr, (int)sizeof(sockaddr_storage));
00776         if (ans != SOCKET_ERROR) {
00777             assert(ans == (int)len);
00778             return RESULT_OK;
00779         } else {
00780            switch(WSAGetLastError()) {
00781             case WSAETIMEDOUT:
00782                 return RESULT_OPERATION_TIMEOUT;
00783             case WSAEMSGSIZE:
00784                 return RESULT_INVALID_DATA;
00785             default:
00786                 return RESULT_OPERATION_FAIL;
00787             }
00788         }
00789 
00790     }
00791 
00792 
00793     virtual u_result recvFrom(void *buf, size_t len, size_t & recv_len, SocketAddress * sourceAddr)
00794     {
00795         struct sockaddr * addr = (sourceAddr?reinterpret_cast<struct sockaddr *>(const_cast<void *>(sourceAddr->getPlatformData())):NULL);
00796         int source_addr_size = (sourceAddr?sizeof(sockaddr_storage):0);
00797 
00798         int ans = ::recvfrom( _socket_fd, (char *)buf, (int)len, 0, addr, addr?&source_addr_size:NULL);
00799         if (ans == SOCKET_ERROR) {
00800             recv_len = 0;  
00801             int errCode = WSAGetLastError();
00802            switch(errCode) {
00803             case WSAETIMEDOUT:
00804                 return RESULT_OPERATION_TIMEOUT;
00805             default:
00806                 return RESULT_OPERATION_FAIL;
00807             }
00808         } else {
00809             recv_len = ans;
00810             return RESULT_OK;
00811         }
00812 
00813     }
00814 
00815 
00816     
00817 protected:
00818     SOCKET  _socket_fd;
00819 
00820 };
00821 
00822 
00823 }}}
00824 
00825 
00826 namespace rp { namespace net{ 
00827 
00828 
00829 
00830 static inline int _socketHalFamilyToOSFamily(SocketBase::socket_family_t family)
00831 {
00832     switch (family) {
00833         case SocketBase::SOCKET_FAMILY_INET:
00834             return AF_INET;
00835         case SocketBase::SOCKET_FAMILY_INET6:
00836             return AF_INET6;
00837         case SocketBase::SOCKET_FAMILY_RAW:
00838             return AF_UNSPEC; //win32 doesn't support RAW Packet
00839         default:
00840             assert(!"should not reach here");
00841             return AF_INET; // force treating as IPv4 in release mode
00842     }
00843 
00844 }
00845 
00846 StreamSocket * StreamSocket::CreateSocket(SocketBase::socket_family_t family)
00847 {
00848     _checkWSAStartup();
00849     if (family == SOCKET_FAMILY_RAW) return NULL;
00850 
00851 
00852     int socket_family = _socketHalFamilyToOSFamily(family);
00853     int socket_fd = ::socket(socket_family, SOCK_STREAM, 0);
00854     if (socket_fd == -1) return NULL;
00855     StreamSocket * newborn = static_cast<StreamSocket *>(new rp::arch::net::StreamSocketImpl(socket_fd));
00856     return newborn;
00857 
00858 }
00859 
00860 
00861 DGramSocket * DGramSocket::CreateSocket(SocketBase::socket_family_t family)
00862 {
00863     _checkWSAStartup();
00864     int socket_family = _socketHalFamilyToOSFamily(family);
00865 
00866 
00867     int socket_fd = ::socket(socket_family, (family==SOCKET_FAMILY_RAW)?SOCK_RAW:SOCK_DGRAM, 0);
00868     if (socket_fd == -1) return NULL;
00869     DGramSocket * newborn = static_cast<DGramSocket *>(new rp::arch::net::DGramSocketImpl(socket_fd));
00870     return newborn;
00871 
00872 }
00873 
00874 
00875 }}
00876 


rplidar_ros
Author(s):
autogenerated on Mon Mar 18 2019 02:34:23