SWIsocket.cpp
上传用户:xqtpzdz
上传日期:2022-05-21
资源大小:1764k
文件大小:20k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. /****************License************************************************
  2.  * Vocalocity OpenVXI
  3.  * Copyright (C) 2004-2005 by Vocalocity, Inc. All Rights Reserved.
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *  
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  * Vocalocity, the Vocalocity logo, and VocalOS are trademarks or 
  18.  * registered trademarks of Vocalocity, Inc. 
  19.  * OpenVXI is a trademark of Scansoft, Inc. and used under license 
  20.  * by Vocalocity.
  21.  ***********************************************************************/
  22. #if _MSC_VER >= 1100    // Visual C++ 5.x
  23. #pragma warning( disable : 4786 4503 )
  24. #endif
  25. #ifdef _WIN32
  26. #include <winsock2.h>
  27. #define WSA_LAST_ERROR WSAGetLastError()
  28. #define WSA_ERROR_NAME L"WinsockError"
  29. #else
  30. #include <sys/types.h>
  31. #include <arpa/inet.h>
  32. #include <sys/socket.h>
  33. #include <unistd.h>
  34. #include <errno.h>
  35. #include <sys/ioctl.h>
  36. #ifdef _solaris_
  37. #include <stropts.h>
  38. #include <fcntl.h>
  39. #include <string.h>
  40. #endif
  41. #define WSA_LAST_ERROR errno
  42. #define WSA_ERROR_NAME L"errno"
  43. #define WSAEADDRINUSE EADDRINUSE
  44. #define WSAECONNABORTED ECONNABORTED
  45. #define WSAECONNRESET ECONNRESET
  46. #define WSAECONNREFUSED ECONNREFUSED
  47. #define WSAEHOSTDOWN EHOSTDOWN
  48. #define WSAEHOSTUNREACH EHOSTUNREACH
  49. #define WSAEWOULDBLOCK EINPROGRESS
  50. #define WSAEACCESS EACCESS
  51. #define WSAENOTSOCK EBADF
  52. #define WSAEINTR EINTR
  53. #define closesocket close
  54. #define ioctlsocket ioctl
  55. #endif
  56. #include "SWIsocket.hpp"
  57. #include "SWIipAddress.hpp"
  58. static timeval* millisecToTimeval(long millisec, timeval& tv)
  59. {
  60.   if (millisec < 0)
  61.   {
  62.     tv.tv_sec  = -1;
  63.     tv.tv_usec = -1;
  64.     return NULL;
  65.   }
  66.   tv.tv_sec = (millisec / 1000);
  67.   tv.tv_usec = (millisec % 1000) * 1000;
  68.   return &tv;
  69. }
  70. SWIsocket::SWIsocket(Type socktype,
  71.                      SWIutilLogger *logger):
  72.   _logger(logger), _sd(INVALID_SOCKET),
  73.   _bound(false), _connected(false), _shutIn(false), _shutOut(false),
  74.   _remoteAddress(NULL), _localAddress(NULL), _rtmo(-1), _stmo(-1),
  75.   _inStream(NULL), _outStream(NULL)
  76. {
  77.   _sd = socket(AF_INET, socktype, 0);
  78.   if (_sd == INVALID_SOCKET)
  79.   {
  80.     error(L"socket", 500, WSA_LAST_ERROR);
  81.   }
  82. }
  83. SWIsocket::SWIsocket(const SWIsocket *socket, SOCKET sd):
  84.   _logger(socket->_logger), _sd(sd), _bound(true), _connected(true),
  85.   _shutIn(false), _shutOut(false),
  86.   _remoteAddress(NULL), _localAddress(NULL),
  87.   _rtmo(socket->_rtmo), _stmo(socket->_stmo),
  88.   _inStream(NULL), _outStream(NULL)
  89. {}
  90. SWIsocket::~SWIsocket()
  91. {
  92.   close();
  93.   if (_inStream != NULL)
  94.   {
  95.     _inStream->_sock = NULL;
  96.   }
  97.   if (_outStream != NULL)
  98.   {
  99.     _outStream->_sock = NULL;
  100.   }
  101.   delete _remoteAddress;
  102.   delete _localAddress;
  103. }
  104. SWIstream::Result SWIsocket::connect(const SWIipAddress& endpoint, long timeout)
  105. {
  106.   SWIstream::Result rc = SWIstream::SUCCESS;
  107.   unsigned long nonblocking = 1;
  108.   int flags = 0;
  109.   timeval tv;
  110.   timeval *ptv = millisecToTimeval(timeout, tv);
  111.   if (ptv != NULL)
  112.   {
  113. #ifdef _solaris_
  114. flags = fcntl(_sd, F_GETFL, 0);
  115. flags  |= O_NONBLOCK;
  116. fcntl(_sd, F_SETFL, flags);
  117. #else
  118.     ioctlsocket(_sd, FIONBIO, &nonblocking);
  119.     nonblocking = 0;
  120. #endif
  121.   }
  122.   if (::connect(_sd, endpoint.addr(), endpoint.size()) != 0)
  123.   {
  124.     int wserr = WSA_LAST_ERROR;
  125.     if (wserr != WSAEWOULDBLOCK)
  126.     {
  127.       error(L"connect", 500, wserr);
  128.       rc = SWIstream::FAILURE;
  129.       goto cleanup;
  130.     }
  131.   }
  132.   if (ptv != NULL)
  133.   {
  134.     int status = is_writeready(ptv);
  135.     if (status == 0)
  136.     {
  137.       rc = SWIstream::TIMED_OUT;
  138.       goto cleanup;
  139.     }
  140.     if (status < 0)
  141.     {
  142.       rc = SWIstream::OPEN_ERROR;
  143.       goto cleanup;
  144.     }
  145.   }
  146.   _bound = _connected = true;
  147.  cleanup:
  148.   // restore blocking mode.
  149.   if (ptv != NULL)
  150.   {
  151. #ifdef _solaris_
  152. flags = fcntl(_sd, F_GETFL, 0);
  153. flags &= ~O_NONBLOCK;
  154. fcntl(_sd, F_SETFL, flags);
  155. #else
  156.     ioctlsocket(_sd, FIONBIO, &nonblocking);
  157. #endif
  158.   }
  159.   return rc;
  160. }
  161. SWIstream::Result SWIsocket::connect(const char *hostname, int port, long timeout)
  162. {
  163.   SWIipAddress endpoint(hostname, port, _logger);
  164.   return connect(endpoint, timeout);
  165. }
  166. SWIstream::Result SWIsocket::connect(unsigned long addr, int port, long timeout)
  167. {
  168.   SWIipAddress endpoint(addr, port, _logger);
  169.   return connect(endpoint, timeout);
  170. }
  171. SWIstream::Result SWIsocket::connect(unsigned long addr,
  172.                                      const char *service_name,
  173.                                      const char *protocol_name,
  174.                                      long timeout)
  175. {
  176.   SWIipAddress endpoint(addr, service_name, protocol_name, _logger);
  177.   return connect(endpoint, timeout);
  178. }
  179. SWIstream::Result SWIsocket::connect(const char *host,
  180.                                      const char *service_name,
  181.                                      const char *protocol_name,
  182.                                      long timeout)
  183. {
  184.   SWIipAddress endpoint(host, service_name, protocol_name, _logger);
  185.   return connect(endpoint, timeout);
  186. }
  187. SWIstream::Result SWIsocket::bind(const SWIipAddress& sa)
  188. {
  189.   int rc = ::bind(_sd, sa.addr (), sa.size ());
  190.   if (rc != 0)
  191.   {
  192.     error(L"bind", 500, WSA_LAST_ERROR);
  193.     return SWIstream::FAILURE;
  194.   }
  195.   _bound = true;
  196.   return SWIstream::SUCCESS;
  197. }
  198. SWIstream::Result SWIsocket::bind()
  199. {
  200.   SWIipAddress sa(_logger);
  201.   return bind(sa);
  202. }
  203. SWIstream::Result SWIsocket::bind(unsigned long addr, int port_no)
  204. {
  205.   SWIipAddress sa(addr, port_no, _logger);
  206.   return bind(sa);
  207. }
  208. SWIstream::Result SWIsocket::bind(const char* host_name, int port_no)
  209. {
  210.   SWIipAddress sa(host_name, port_no, _logger);
  211.   return bind (sa);
  212. }
  213. SWIstream::Result SWIsocket::bind(unsigned long addr,
  214.                                   const char* service_name,
  215.                                   const char* protocol_name)
  216. {
  217.   SWIipAddress sa(addr, service_name, protocol_name, _logger);
  218.   return bind(sa);
  219. }
  220. SWIstream::Result SWIsocket::bind(const char* host_name,
  221.                                   const char* service_name,
  222.                                   const char* protocol_name)
  223. {
  224.   SWIipAddress sa(host_name, service_name, protocol_name, _logger);
  225.   return bind(sa);
  226. }
  227. SWIstream::Result SWIsocket::listen(int backlog)
  228. {
  229.   int rc = ::listen (_sd, backlog);
  230.   if (rc != 0)
  231.   {
  232.     error(L"listen", 500, WSA_LAST_ERROR);
  233.     return SWIstream::FAILURE;
  234.   }
  235.   return SWIstream::SUCCESS;
  236. }
  237. SWIsocket *SWIsocket::accept(SWIipAddress& sa)
  238. {
  239.   int wserr;
  240.   socklen_t len = sa.size();
  241.   SOCKET soc = INVALID_SOCKET;
  242.   while ((soc = ::accept (_sd, sa.addr(), &len)) == INVALID_SOCKET
  243.  && (wserr = WSA_LAST_ERROR) == WSAEINTR);
  244.   if (soc == INVALID_SOCKET)
  245.   {
  246.     error(L"accept", 500, wserr);
  247.     return NULL;
  248.   }
  249.   return new SWIsocket(this, soc);
  250. }
  251. SWIsocket* SWIsocket::accept()
  252. {
  253.   int wserr;
  254.   SOCKET soc = INVALID_SOCKET;
  255.   while ((soc = ::accept (_sd, NULL, NULL)) == INVALID_SOCKET
  256.  && (wserr = WSA_LAST_ERROR) == WSAEINTR);
  257.   if (soc == INVALID_SOCKET)
  258.   {
  259.     error(L"accept", 500, wserr);
  260.     return NULL;
  261.   }
  262.   return new SWIsocket(this, soc);
  263. }
  264. const SWIipAddress *SWIsocket::getRemoteAddress() const
  265. {
  266.   //   if (!_connected)
  267.   //     return NULL;
  268.   if (_remoteAddress != NULL)
  269.     return _remoteAddress;
  270.   _remoteAddress = new SWIipAddress(_logger);
  271.   socklen_t len = _remoteAddress->size();
  272.   if (::getpeername(_sd, _remoteAddress->addr(), &len) != 0)
  273.   {
  274.     error(L"getpeername", 500, WSA_LAST_ERROR);
  275.     delete _remoteAddress;
  276.     _remoteAddress = NULL;
  277.   }
  278.   return _remoteAddress;
  279. }
  280. const SWIipAddress *SWIsocket::getLocalAddress() const
  281. {
  282.   //if (!_bound)
  283.   //return NULL;
  284.   if (_localAddress != NULL)
  285.     return _localAddress;
  286.   _localAddress = new SWIipAddress(_logger);
  287.   socklen_t len = _localAddress->size();
  288.   if (::getsockname(_sd, _localAddress->addr(), &len) != 0)
  289.   {
  290.     error(L"getsockname", 500, WSA_LAST_ERROR);
  291.     delete _localAddress;
  292.     _localAddress = NULL;
  293.   }
  294.   return _localAddress;
  295. }
  296. int SWIsocket::getRemotePort() const
  297. {
  298.   const SWIipAddress* addr = getRemoteAddress();
  299.   if (addr == NULL)
  300.   {
  301.     return 0;
  302.   }
  303.   else
  304.     return addr->getport();
  305. }
  306. int SWIsocket::getLocalPort() const
  307. {
  308.   const SWIipAddress* addr = getLocalAddress();
  309.   if (addr == NULL)
  310.   {
  311.     return 0;
  312.   }
  313.   else
  314.     return addr->getport();
  315. }
  316. SWIstream::Result SWIsocket::close()
  317. {
  318.   if (_sd != INVALID_SOCKET)
  319.   {
  320.     ::closesocket(_sd);
  321.     _sd = INVALID_SOCKET;
  322.   }
  323.   return SWIstream::SUCCESS;
  324. }
  325. SWIinputStream *SWIsocket::getInputStream()
  326. {
  327.   if (_inStream == NULL)
  328.   {
  329.     _inStream = new InputStream(this);
  330.   }
  331.   return _inStream;
  332. }
  333. SWIoutputStream *SWIsocket::getOutputStream()
  334. {
  335.   if (_outStream == NULL)
  336.   {
  337.     _outStream = new OutputStream(this);
  338.   }
  339.   return _outStream;
  340. }
  341. SWIsocket::InputStream::InputStream(SWIsocket *sock):
  342.   _sock(sock)
  343. {}
  344. SWIsocket::InputStream::~InputStream()
  345. {
  346.   if (_sock != NULL)
  347.   {
  348.     _sock->shutdown(shut_read);
  349.     _sock->_inStream = NULL;
  350.   }
  351. }
  352. int SWIsocket::InputStream::readBytes(void *data, int dataSize)
  353. {
  354.   return _sock != NULL ? _sock->recv(data, dataSize) : SWIstream::ILLEGAL_STATE;
  355. }
  356. SWIstream::Result SWIsocket::InputStream::close()
  357. {
  358.   if (_sock == NULL)
  359.     return SWIstream::ILLEGAL_STATE;
  360.   return _sock->shutdown(shut_read);
  361. }
  362. SWIstream::Result SWIsocket::InputStream::waitReady(long timeoutMs)
  363. {
  364.   if (_sock == NULL)
  365.     return SWIstream::ILLEGAL_STATE;
  366.   switch (_sock->is_readready(timeoutMs))
  367.   {
  368.    case 1:
  369.      return SUCCESS;
  370.    case 0:
  371.      return TIMED_OUT;
  372.    default:
  373.      return FAILURE;
  374.   }
  375. }
  376. SWIsocket::OutputStream::OutputStream(SWIsocket *sock):
  377.   _sock(sock)
  378. {}
  379. SWIsocket::OutputStream::~OutputStream()
  380. {
  381.   if (_sock != NULL)
  382.   {
  383.     _sock->shutdown(shut_write);
  384.     _sock->_outStream = NULL;
  385.   }
  386. }
  387. int SWIsocket::OutputStream::writeBytes(const void *buffer, int bufferSize)
  388. {
  389.   return _sock != NULL ? _sock->send(buffer, bufferSize) : SWIstream::ILLEGAL_STATE;
  390. }
  391. SWIstream::Result SWIsocket::OutputStream::close()
  392. {
  393.   if (_sock == NULL)
  394.     return SWIstream::ILLEGAL_STATE;
  395.   return _sock->shutdown(shut_write);
  396. }
  397. SWIstream::Result SWIsocket::OutputStream::waitReady(long timeoutMs)
  398. {
  399.   if (_sock == NULL)
  400.     return SWIstream::ILLEGAL_STATE;
  401.   switch (_sock->is_writeready(timeoutMs))
  402.   {
  403.    case 1:
  404.      return SUCCESS;
  405.    case 0:
  406.      return TIMED_OUT;
  407.    default:
  408.      return FAILURE;
  409.   }
  410. }
  411. int SWIsocket::read(void* buf, int len)
  412. {
  413. #ifdef _WIN32
  414.   return recv(buf, len); // Winsock uses recv
  415. #else
  416.   if (_rtmo != -1 && is_readready(_rtmo) == 0)
  417.     return SWIstream::TIMED_OUT;
  418.   int rval = ::read(_sd, (char *) buf, len);
  419.   switch (rval)
  420.   {
  421.    case -1:
  422.      {
  423.        int wserr = WSA_LAST_ERROR;
  424.        if (wserr == WSAECONNABORTED || wserr == WSAECONNRESET)
  425.        {
  426.          rval = SWIstream::CONNECTION_ABORTED;
  427.        }
  428.        else
  429.        {
  430.          error(L"read", 500, wserr);
  431.          rval = SWIstream::READ_ERROR;
  432.        }
  433.        break;
  434.      }
  435.    case 0:
  436.      rval = SWIstream::END_OF_FILE;
  437.      break;
  438.    default:
  439.      break;
  440.   }
  441.   return rval;
  442. #endif // _WIN32
  443. }
  444. int SWIsocket::recv(void* buf, int len, int msgf)
  445. {
  446.   if (_rtmo != -1 && is_readready (_rtmo)==0)
  447.     return SWIstream::TIMED_OUT;
  448.   int rval = ::recv(_sd, (char*) buf, len, msgf);
  449.   switch (rval)
  450.   {
  451.    case -1:
  452.      {
  453.        int wserr = WSA_LAST_ERROR;
  454.        if (wserr == WSAECONNABORTED || wserr == WSAECONNRESET)
  455.        {
  456.          rval = SWIstream::CONNECTION_ABORTED;
  457.        }
  458.        else
  459.        {
  460.          error(L"recv", 500, wserr);
  461.          rval = SWIstream::READ_ERROR;
  462.        }
  463.      }
  464.      break;
  465.    case 0:
  466.      rval = SWIstream::END_OF_FILE;
  467.      break;
  468.    default:
  469.      break;
  470.   }
  471.   return rval;
  472. }
  473. int SWIsocket::recvfrom (SWIipAddress& sa, void* buf, int len, int msgf)
  474. {
  475.   if (_rtmo != -1 && is_readready (_rtmo)==0)
  476.     return SWIstream::TIMED_OUT;
  477.   socklen_t sa_len = sa.size ();
  478.   int rval = ::recvfrom(_sd, (char*) buf, len,
  479.                         msgf, sa.addr(), &sa_len);
  480.   switch (rval)
  481.   {
  482.    case -1:
  483.      error(L"recvfrom", 500, WSA_LAST_ERROR);
  484.      rval = SWIstream::READ_ERROR;
  485.      break;
  486.    case 0:
  487.      rval = SWIstream::END_OF_FILE;
  488.      break;
  489.    default:
  490.      break;
  491.   }
  492.   return rval;
  493. }
  494. int SWIsocket::write(const void* buf, int len)
  495. {
  496. #ifdef _WIN32
  497.   return send(buf, len); // Winsock uses send
  498. #else
  499.   if (_stmo != -1 && is_writeready (_stmo)==0) return 0;
  500.   int wlen = 0;
  501.   while (len > 0)
  502.   {
  503.     int wval;
  504.     if ((wval = ::write (_sd, (char*) buf, len)) == -1)
  505.     {
  506.       error(L"write", 500, WSA_LAST_ERROR);
  507.       return SWIstream::WRITE_ERROR;
  508.     }
  509.     len -= wval;
  510.     wlen += wval;
  511.   }
  512.   return wlen; // == len if every thing is all right
  513. #endif // _WIN32
  514. }
  515. int SWIsocket::send (const void* buf, int len, int msgf)
  516. {
  517.   if (_stmo != -1 && is_writeready (_stmo)==0) return 0;
  518.   int wlen=0;
  519.   while(len>0) {
  520.     int wval;
  521.     if ((wval = ::send (_sd, (char*) buf, len, msgf)) == -1)
  522.     {
  523.       int wserr = WSA_LAST_ERROR;
  524.       if (wserr == WSAECONNRESET || wserr == WSAECONNABORTED)
  525.       {
  526.         return SWIstream::CONNECTION_ABORTED;
  527.       }
  528.       else
  529.       {
  530.         error(L"send", 500, WSA_LAST_ERROR);
  531.         return SWIstream::WRITE_ERROR;
  532.       }
  533.     }
  534.     len -= wval;
  535.     wlen += wval;
  536.   }
  537.   return wlen;
  538. }
  539. int SWIsocket::sendto(const SWIipAddress& sa, const void* buf, int len, int msgf)
  540. {
  541.   if (_stmo != -1 && is_writeready (_stmo)==0) return 0;
  542.   int wlen=0;
  543.   while(len>0)
  544.   {
  545.     int wval;
  546.     if ((wval = ::sendto (_sd, (char*) buf, len,
  547.   msgf, sa.addr (), sa.size())) == -1)
  548.     {
  549.       error(L"sendto", 500, WSA_LAST_ERROR);
  550.       return SWIstream::WRITE_ERROR;
  551.     }
  552.     len -= wval;
  553.     wlen += wval;
  554.   }
  555.   return wlen;
  556. }
  557. long SWIsocket::sendtimeout(long wp)
  558. {
  559.   long old_stmo = _stmo;
  560.   _stmo = (wp < 0) ? -1: wp;
  561.   return old_stmo;
  562. }
  563. long SWIsocket::recvtimeout(long wp)
  564. {
  565.   long old_rtmo = _rtmo;
  566.   _rtmo = (wp < 0) ? -1: wp;
  567.   return old_rtmo;
  568. }
  569. int SWIsocket::is_readready(timeval *tv) const
  570. {
  571.   fd_set rfds;
  572.   FD_ZERO (&rfds);
  573.   FD_SET (_sd, &rfds);
  574.   fd_set efds;
  575.   FD_ZERO (&efds);
  576.   FD_SET (_sd, &efds);
  577.   int ret = select (_sd + 1, &rfds, 0, &efds, tv);
  578.   if (ret <= 0)
  579.   {
  580.     if (ret < 0) error(L"select", 500, WSA_LAST_ERROR);
  581.     return ret;
  582.   }
  583.   if (FD_ISSET(_sd, &efds))
  584.   {
  585.     int val;
  586.     socklen_t rlen = sizeof val;
  587.     ::getsockopt(_sd, SOL_SOCKET, SO_ERROR, (char *) &val, &rlen);
  588.     error(L"select", 502, val);
  589.     return -1;
  590.   }
  591.   return FD_ISSET(_sd, &rfds);
  592. }
  593. int SWIsocket::is_readready(long timeoutMs) const
  594. {
  595.   timeval tv;
  596.   timeval *ptv = millisecToTimeval(timeoutMs, tv);
  597.   return is_readready(ptv);
  598. }
  599. int SWIsocket::is_writeready(timeval *tv) const
  600. {
  601.   fd_set wfds;
  602.   FD_ZERO (&wfds);
  603.   FD_SET (_sd, &wfds);
  604.   fd_set efds;
  605.   FD_ZERO (&efds);
  606.   FD_SET (_sd, &efds);
  607.   int ret = select (_sd+1, 0, &wfds, &efds, tv);
  608.   if (ret <= 0)
  609.   {
  610.     if (ret < 0) error(L"select", 500, WSA_LAST_ERROR);
  611.     return ret;
  612.   }
  613.   if (FD_ISSET(_sd, &efds))
  614.   {
  615.     int val;
  616.     socklen_t rlen = sizeof val;
  617.     getsockopt(_sd, SOL_SOCKET, SO_ERROR, (char *) &val, &rlen);
  618.     error(L"select", 502, val);
  619.     return -1;
  620.   }
  621.   return FD_ISSET(_sd,&wfds);
  622. }
  623. int SWIsocket::is_writeready(long timeoutMs) const
  624. {
  625.   timeval tv;
  626.   timeval *ptv = millisecToTimeval(timeoutMs, tv);
  627.   return is_writeready(ptv);
  628. }
  629. int SWIsocket::is_exceptionpending(timeval *tv) const
  630. {
  631.   fd_set fds;
  632.   FD_ZERO (&fds);
  633.   FD_SET  (_sd, &fds);
  634.   int ret = select(_sd+1, 0, 0, &fds, tv);
  635.   if (ret == -1)
  636.   {
  637.     error(L"select", 500);
  638.     return 0;
  639.   }
  640.   return ret;
  641. }
  642. int SWIsocket::is_exceptionpending (long timeoutMs) const
  643. {
  644.   timeval tv;
  645.   timeval *ptv = millisecToTimeval(timeoutMs, tv);
  646.   return is_exceptionpending(ptv);
  647. }
  648. SWIstream::Result SWIsocket::shutdown (shuthow sh)
  649. {
  650.   if (::shutdown(_sd, sh) != 0)
  651.   {
  652.     error(L"shutdown", 500);
  653.     return SWIstream::FAILURE;
  654.   }
  655.   return SWIstream::SUCCESS;
  656. }
  657. int SWIsocket::getopt (option op, void* buf, int len, level l) const
  658. {
  659.   socklen_t rlen = len;
  660.   if (::getsockopt (_sd, l, op, (char*) buf, &rlen) == -1)
  661.     error(L"getsockopt", 500);
  662.   return rlen;
  663. }
  664. void SWIsocket::setopt (option op, void* buf, int len, level l) const
  665. {
  666.   if (::setsockopt (_sd, l, op, (char*) buf, len) == -1)
  667.     error (L"setsockopt", 500);
  668. }
  669. SWIsocket::Type SWIsocket::gettype() const
  670. {
  671.   int ty=0;
  672.   getopt (so_type, &ty, sizeof (ty));
  673.   return SWIsocket::Type(ty);
  674. }
  675. int SWIsocket::clearerror () const
  676. {
  677.   int  err=0;
  678.   getopt (so_error, &err, sizeof (err));
  679.   return err;
  680. }
  681. int SWIsocket::debug (int opt) const
  682. {
  683.   int old=0;
  684.   getopt (so_debug, &old, sizeof (old));
  685.   if (opt != -1)
  686.     setopt (so_debug, &opt, sizeof (opt));
  687.   return old;
  688. }
  689. int SWIsocket::reuseaddr (int opt) const
  690. {
  691.   int old=0;
  692.   getopt (so_reuseaddr, &old, sizeof (old));
  693.   if (opt != -1)
  694.     setopt (so_reuseaddr, &opt, sizeof (opt));
  695.   return old;
  696. }
  697. int SWIsocket::keepalive (int opt) const
  698. {
  699.   int old=0;
  700.   getopt (so_keepalive, &old, sizeof (old));
  701.   if (opt != -1)
  702.     setopt (so_keepalive, &opt, sizeof (opt));
  703.   return old;
  704. }
  705. int SWIsocket::dontroute (int opt) const
  706. {
  707.   int old=0;
  708.   getopt (so_dontroute, &old, sizeof (old));
  709.   if (opt != -1)
  710.     setopt (so_dontroute, &opt, sizeof (opt));
  711.   return old;
  712. }
  713. int SWIsocket::broadcast (int opt) const
  714. {
  715.   int old=0;
  716.   getopt (so_broadcast, &old, sizeof (old));
  717.   if (opt != -1)
  718.     setopt (so_broadcast, &opt, sizeof (opt));
  719.   return old;
  720. }
  721. int SWIsocket::oobinline (int opt) const
  722. {
  723.   int old=0;
  724.   getopt (so_oobinline, &old, sizeof (old));
  725.   if (opt != -1)
  726.     setopt (so_oobinline, &opt, sizeof (opt));
  727.   return old;
  728. }
  729. int SWIsocket::linger (int opt) const
  730. {
  731.   socklinger old (0, 0);
  732.   getopt (so_linger, &old, sizeof (old));
  733.   if (opt > 0) {
  734.     socklinger nw (1, opt);
  735.     setopt (so_linger, &nw, sizeof (nw));
  736.   }else if (opt == 0) {
  737.     socklinger nw (0, old.l_linger);
  738.     setopt (so_linger, &nw, sizeof (nw));
  739.   }
  740.   return old.l_onoff ? old.l_linger: -1;
  741. }
  742. int SWIsocket::sendbufsz (int  sz) const
  743. {
  744.   int old=0;
  745.   getopt (so_sndbuf, &old, sizeof (old));
  746.   if (sz >= 0)
  747.     setopt (so_sndbuf, &sz, sizeof (sz));
  748.   return old;
  749. }
  750. int SWIsocket::recvbufsz (int sz) const
  751. {
  752.   int old=0;
  753.   getopt (so_rcvbuf, &old, sizeof (old));
  754.   if (sz >= 0)
  755.     setopt (so_rcvbuf, &sz, sizeof (sz));
  756.   return old;
  757. }
  758. void SWIsocket::error(const VXIchar* func, VXIunsigned errorId,
  759.                       const VXIchar *errorName, int errorCode) const
  760. {
  761.   if (_logger)
  762.   {
  763.     _logger->Error(errorId, L"%s%s%s%i",
  764.                    L"Func", func,
  765.                    errorName, errorCode);
  766.   }
  767. }
  768. void SWIsocket::error(const VXIchar* func, VXIunsigned errorId, int errorCode) const
  769. {
  770.   if (_logger)
  771.   {
  772.     _logger->Error(errorId, L"%s%s%s%i",
  773.                    L"Func",
  774.                    func,
  775.                    WSA_ERROR_NAME, errorCode);
  776.   }
  777. }
  778. void SWIsocket::error(const VXIchar* func, VXIunsigned errorId) const
  779. {
  780.   if (_logger)
  781.   {
  782.     _logger->Error(errorId, L"%s%s", L"Func", func);
  783.   }
  784. }