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

xml/soap/webservice

开发平台:

Visual C++

  1. // sockinet.C  -*- C++ -*- socket library
  2. // Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
  3. //
  4. // Permission is granted to use at your own risk and distribute this software
  5. // in source and binary forms provided the above copyright
  6. // notice and this paragraph are preserved on all copies.
  7. // This software is provided "as is" with no express or implied warranty.
  8. //
  9. // Version: 17Oct95 1.10
  10. #include "SWIutilInternal.h"
  11. #include "sockinet.h"
  12. #ifndef _WIN32
  13. EXTERN_C_BEGIN
  14. #include <netdb.h>
  15. #include <sys/time.h>
  16. #include <sys/socket.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <errno.h>
  20. EXTERN_C_END
  21. #else
  22. #include <winsock.h>
  23. #define EADDRINUSE WSAEADDRINUSE
  24. #endif /* !_WIN32 */
  25. #if defined(WIN32) || defined(_decunix_)
  26. /* These OSes are thread safe by using thread local storage for the hostent */
  27. static int my_gethostbyaddr_r (const char * addr, socklen_t len,
  28.        int type,
  29.        struct hostent * result_buf,
  30.        char * buf, size_t buflen,
  31.        struct hostent ** result,
  32.        int * h_errnop) {
  33.   *result = gethostbyaddr(addr, len, type);
  34.   return (result ? 0 : -1);
  35. }
  36. static int my_gethostbyname_r (const char * name,
  37.        struct hostent * result_buf,
  38.        char * buf, size_t buflen,
  39.        struct hostent ** result,
  40.        int * h_errnop) {
  41.   *result = gethostbyname(name);
  42.   return (result ? 0 : -1);
  43. }
  44. #elif defined(_solaris_)
  45. static int my_gethostbyaddr_r (const char * addr, socklen_t len,
  46.        int type,
  47.        struct hostent * result_buf,
  48.        char * buf, size_t buflen,
  49.        struct hostent ** result,
  50.        int * h_errnop) {
  51.   *result = gethostbyaddr_r(addr, len, type, result_buf, buf, buflen,
  52.     h_errnop);
  53.   return (result ? 0 : -1);
  54. }
  55. static int my_gethostbyname_r (const char * name,
  56.        struct hostent * result_buf,
  57.        char * buf, size_t buflen,
  58.        struct hostent ** result,
  59.        int * h_errnop) {
  60.   *result = gethostbyname_r(name, result_buf, buf, buflen, h_errnop);
  61.   return (result ? 0 : -1);
  62. }
  63. #else
  64. /* Linux, maybe others */
  65. #define my_gethostbyaddr_r gethostbyaddr_r
  66. #define my_gethostbyname_r gethostbyname_r
  67. #endif
  68. sockinetaddr::sockinetaddr (const sockinetaddr &sina)
  69.   : sockAddr (sina.GetModuleName( ), sina.GetLog( ), sina.GetDiagBase( ))
  70. {
  71.   sin_family      = sina.sin_family;
  72.   sin_addr.s_addr = sina.sin_addr.s_addr;
  73.   sin_port   = sina.sin_port;
  74. }
  75. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  76.    VXIunsigned diagTagBase)
  77.   : sockAddr (moduleName, pVXILog, diagTagBase)
  78. {
  79.   sin_family   = sockinetbuf::af_inet;
  80.   sin_addr.s_addr = htonl(INADDR_ANY);
  81.   sin_port   = 0;
  82. }
  83. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  84.    VXIunsigned diagTagBase, unsigned long addr,
  85.    int port_no)
  86.   : sockAddr (moduleName, pVXILog, diagTagBase)
  87. // addr and port_no are in host byte order
  88. {
  89.   sin_family      = sockinetbuf::af_inet;
  90.   sin_addr.s_addr = htonl(addr);
  91.   sin_port   = htons(port_no);
  92. }
  93. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  94.    VXIunsigned diagTagBase, unsigned long addr,
  95.    const char* sn, const char* pn)
  96.   : sockAddr (moduleName, pVXILog, diagTagBase)
  97. // addr is in host byte order
  98. {
  99.   sin_family      = sockinetbuf::af_inet;
  100.   sin_addr.s_addr = htonl (addr); // Added by cgay@cs.uoregon.edu May 29, 1993
  101.   setport(sn, pn);
  102. }
  103. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  104.    VXIunsigned diagTagBase, const char* host_name,
  105.    int port_no)
  106.   : sockAddr (moduleName, pVXILog, diagTagBase)
  107. // port_no is in host byte order
  108. {
  109.   setaddr(host_name);
  110.   sin_port = htons(port_no);
  111. }
  112. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  113.    VXIunsigned diagTagBase, const char* hn, 
  114.    const char* sn, const char* pn)
  115.   : sockAddr (moduleName, pVXILog, diagTagBase)
  116. {
  117.   setaddr(hn);
  118.   setport(sn, pn);
  119. }
  120. sockinetaddr::sockinetaddr(const VXIchar *moduleName, VXIlogInterface *pVXILog,
  121.    VXIunsigned diagTagBase, const sockinetaddr& sina)
  122.   : sockAddr (moduleName, pVXILog, diagTagBase)
  123. {
  124.   sin_family      = sina.sin_family;
  125.   sin_addr.s_addr = sina.sin_addr.s_addr;
  126.   sin_port   = sina.sin_port;
  127. }
  128. int sockinetaddr::setport(const char* sn, const char* pn)
  129. {
  130.   servent* sp = getservbyname(sn, pn);
  131.   if (sp == 0)
  132.   {
  133.     SOCK_ERROR("sockinetaddr", "invalid service name");
  134.     return -1;
  135.   }
  136.   sin_port = sp->s_port;
  137.   return 0;
  138. }
  139. int sockinetaddr::getport () const
  140. {
  141.   return ntohs (sin_port);
  142. }
  143. int sockinetaddr::setaddr(const char* host_name)
  144. {
  145.   if ( (sin_addr.s_addr = inet_addr(host_name)) == (in_addr_t) -1) {
  146.     int hostErrno;
  147.     struct hostent hostResult;
  148.     char hostBuffer[4096];
  149.     hostent* hp;
  150.     if ((my_gethostbyname_r(host_name, &hostResult, hostBuffer,
  151.     2048, &hp, &hostErrno) != 0) ||
  152. (hp == 0))
  153.     {
  154.       return -1;
  155.     }
  156.     memcpy(&sin_addr, hp->h_addr, hp->h_length);
  157.     sin_family = hp->h_addrtype;
  158.   }
  159.   else
  160.     sin_family = sockinetbuf::af_inet;
  161.   return 0;
  162. }
  163. int sockinetaddr::gethostname (char *hostname, size_t hostnameLen) const
  164. {
  165.   hostname[0] = '';
  166.   if (sin_addr.s_addr == htonl(INADDR_ANY)) {
  167.     if (::gethostname(hostname, hostnameLen) == -1) {
  168.       SOCK_ERROR("sockinetaddr", "gethostname");
  169.       hostname[0] = '';
  170.       return -1;
  171.     }
  172.     return 0;
  173.   }
  174.   int hostErrno;
  175.   struct hostent hostResult;
  176.   char hostBuffer[4096];
  177.   hostent* hp;
  178.   if ((my_gethostbyaddr_r((const char*) &sin_addr, sizeof(sin_addr),
  179.   family(), &hostResult, hostBuffer, 2048, &hp,
  180.   &hostErrno) != 0) ||
  181.       (hp == 0))
  182.   {
  183.     sockinetaddr::herror("gethostbyaddr");
  184.     return -1;
  185.   }
  186.   if ((hp->h_name) && (strlen(hp->h_name) < hostnameLen)) {
  187.     strcpy (hostname, hp->h_name);
  188.     return 0;
  189.   }
  190.   return -1;
  191. }
  192. sockinetbuf::sockinetbuf(const VXIchar *moduleName, VXIlogInterface *pVXILog, 
  193.  VXIunsigned diagTagBase, 
  194.  sockbuf::type ty, int proto)
  195.   : sockbuf(moduleName, pVXILog, diagTagBase, af_inet, ty, proto)
  196. {}
  197. sockinetbuf& sockinetbuf::operator = (const sockbuf& si)
  198. {
  199.   this->sockbuf::operator = (si);
  200.   return *this;
  201. }
  202. sockinetbuf& sockinetbuf::operator = (const sockinetbuf& si)
  203. {
  204.   this->sockbuf::operator = (si);
  205.   return *this;
  206. }
  207. sockbuf* sockinetbuf::open(const VXIchar *moduleName, 
  208.    VXIlogInterface *pVXILog, 
  209.    VXIunsigned diagTagBase,
  210.    sockbuf::type st, int proto)
  211. {
  212.   *this = sockinetbuf(moduleName, pVXILog, diagTagBase, st, proto);
  213.   return this;
  214. }
  215. sockinetaddr sockinetbuf::localaddr() const
  216. {
  217.   sockinetaddr sin (GetModuleName(), GetLog(), GetDiagBase());
  218.   socklen_t len = sin.size();
  219.   if (::getsockname(rep->sock, sin.addr (), &len) == -1)
  220.     SOCK_ERROR("sockinetbuf", "getsockname");
  221.   return sin;
  222. }
  223. int sockinetbuf::localport() const
  224. {
  225.   sockinetaddr sin (localaddr());
  226.   if (sin.family() != af_inet) return -1;
  227.   return sin.getport();
  228. }
  229. int sockinetbuf::localhost(char *hostname, size_t hostnameLen) const
  230. {
  231.   hostname[0] = '';
  232.   sockinetaddr sin (localaddr());
  233.   if (sin.family() != af_inet) return -1;
  234.   return sin.gethostname(hostname, hostnameLen);
  235. }
  236. sockinetaddr sockinetbuf::peeraddr() const
  237. {
  238.   sockinetaddr sin (GetModuleName(), GetLog(), GetDiagBase());
  239.   socklen_t len = sin.size();
  240.   if (::getpeername(rep->sock, sin.addr (), &len) == -1)
  241.     SOCK_ERROR("sockinetbuf", "getpeername");
  242.   return sin;
  243. }
  244. int sockinetbuf::peerport() const
  245. {
  246.   sockinetaddr sin = peeraddr();
  247.   if (sin.family() != af_inet) return -1;
  248.   return sin.getport();
  249. }
  250. int sockinetbuf::peerhost(char *hostname, size_t hostnameLen) const
  251. {
  252.   hostname[0] = '';
  253.   sockinetaddr sin = peeraddr();
  254.   if (sin.family() != af_inet) return -1;
  255.   return sin.gethostname(hostname, hostnameLen);
  256. }
  257. int sockinetbuf::bind_until_success (int portno)
  258. // a. bind to (INADDR_ANY, portno)
  259. // b. if success return 0
  260. // c. if failure and errno is EADDRINUSE, portno++ and go to step a.
  261. // d. return errno.
  262. {
  263.   for (;;) {
  264.     sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), 
  265.      (unsigned long) INADDR_ANY, portno++);
  266.     int eno = bind (sa);
  267.     if (eno == 0)
  268.       return 0;
  269.     if (errno != EADDRINUSE)
  270.       return errno;
  271.   }
  272. }
  273. int sockinetbuf::bind (sockAddr& sa)
  274. {
  275.   return sockbuf::bind (sa);
  276. }
  277. int sockinetbuf::bind ()
  278. {
  279.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase());
  280.   return bind (sa);
  281. }
  282. int sockinetbuf::bind (unsigned long addr, int port_no)
  283. // address and portno are in host byte order
  284. {
  285.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), addr, port_no);
  286.   return bind (sa);
  287. }
  288. int sockinetbuf::bind (const char* host_name, int port_no)
  289. {
  290.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), host_name,
  291.    port_no);
  292.   return bind (sa);
  293. }
  294. int sockinetbuf::bind (unsigned long addr,
  295.        const char* service_name,
  296.        const char* protocol_name)
  297. {
  298.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), addr,
  299.    service_name, protocol_name);
  300.   return bind (sa);
  301. }
  302. int sockinetbuf::bind (const char* host_name,
  303.        const char* service_name,
  304.        const char* protocol_name)
  305. {
  306.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), host_name,
  307.    service_name, protocol_name);
  308.   return bind (sa);
  309. }
  310. int sockinetbuf::connect (sockAddr& sa)
  311. {
  312.   return sockbuf::connect (sa);
  313. }
  314. int sockinetbuf::connect (unsigned long addr, int port_no)
  315. // address and portno are in host byte order
  316. {
  317.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), addr, port_no);
  318.   return connect (sa);
  319. }
  320. int sockinetbuf::connect (const char* host_name, int port_no)
  321. {
  322.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), host_name,
  323.    port_no);
  324.   return connect (sa);
  325. }
  326. int sockinetbuf::connect (unsigned long addr,
  327.   const char* service_name,
  328.   const char* protocol_name)
  329. {
  330.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), addr,
  331.    service_name, protocol_name);
  332.   return connect (sa);
  333. }
  334. int sockinetbuf::connect (const char* host_name,
  335.   const char* service_name,
  336.   const char* protocol_name)
  337. {
  338.   sockinetaddr sa (GetModuleName(), GetLog(), GetDiagBase(), host_name,
  339.    service_name, protocol_name);
  340.   return connect (sa);
  341. }
  342. isockinet::isockinet (const VXIchar *moduleName, VXIlogInterface *pVXILog, 
  343.       VXIunsigned diagTagBase,
  344.                       sockbuf::type ty, int proto)
  345. #ifdef ALLOCATE_STREAMBUF
  346.   : isockstream (new sockinetbuf (moduleName, pVXILog, diagTagBase, ty,
  347.   proto))
  348. #else
  349.   : isockstream (&_mysb), _mysb (moduleName, pVXILog, diagTagBase, ty, proto)
  350. #endif
  351. {}
  352. isockinet::isockinet (const sockbuf& sb)
  353. #ifdef ALLOCATE_STREAMBUF
  354.   : isockstream (new sockinetbuf (sb))
  355. #else
  356.   : isockstream (&_mysb), _mysb(sb)
  357. #endif
  358. {}
  359. isockinet::~isockinet ()
  360. {
  361. #ifdef ALLOCATE_STREAMBUF
  362.   delete ios::rdbuf ();
  363. #endif
  364. #ifdef INIT_IN_DESTRUCTOR
  365.   init (0);
  366. #endif
  367. }
  368. osockinet::osockinet (const VXIchar *moduleName, VXIlogInterface *pVXILog, 
  369.       VXIunsigned diagTagBase,
  370.                       sockbuf::type ty, int proto)
  371. #ifdef ALLOCATE_STREAMBUF
  372.   : osockstream (new sockinetbuf (moduleName, pVXILog, diagTagBase, ty,
  373.   proto))
  374. #else
  375.   : osockstream (&_mysb), _mysb (moduleName, pVXILog, diagTagBase, ty, proto)
  376. #endif
  377. {}
  378. osockinet::osockinet (const sockbuf& sb)
  379. #ifdef ALLOCATE_STREAMBUF
  380.   : osockstream(new sockinetbuf (sb))
  381. #else
  382.   : osockstream(&_mysb), _mysb (sb)
  383. #endif
  384. {}
  385. osockinet::~osockinet ()
  386. {
  387. #ifdef ALLOCATE_STREAMBUF
  388.   delete ios::rdbuf ();
  389. #endif
  390. #ifdef INIT_IN_DESTRUCTOR
  391.   init (0);
  392. #endif
  393. }
  394. iosockinet::iosockinet (const VXIchar *moduleName, VXIlogInterface *pVXILog, 
  395. VXIunsigned diagTagBase, 
  396.                         sockbuf::type ty, int proto)
  397. #ifdef ALLOCATE_STREAMBUF
  398.   : iosockstream(new sockinetbuf (moduleName, pVXILog, diagTagBase, ty, proto))
  399. #else
  400.   : iosockstream(&_mysb), _mysb (moduleName, pVXILog, diagTagBase, ty, proto)
  401. #endif
  402. {}
  403. iosockinet::iosockinet (const sockbuf& sb)
  404. #ifdef ALLOCATE_STREAMBUF
  405.   : iosockstream(new sockinetbuf (sb))
  406. #else
  407.   : iosockstream(&_mysb), _mysb (sb)
  408. #endif
  409. {}
  410. iosockinet::~iosockinet ()
  411. {
  412. #ifdef ALLOCATE_STREAMBUF
  413.   delete ios::rdbuf ();
  414. #endif
  415. #ifdef INIT_IN_DESTRUCTOR
  416.   init (0);
  417. #endif
  418. }
  419. #ifdef _WIN32
  420. static char* errmsg[] = {
  421.   "No error",
  422.   "Host not found",
  423.   "Try again",
  424.   "No recovery",
  425.   "No address"
  426.   "Unknown error"
  427. };
  428. /* Winsock.h maps h_errno to WSAGetLastError() function call */
  429. void sockinetaddr::herror(const char* em) const
  430. {
  431.   int err;
  432.   switch(h_errno) { /* calls WSAGetLastError() */
  433.    case HOST_NOT_FOUND:
  434.      err = 1;
  435.      break;
  436.    case TRY_AGAIN:
  437.      err = 2;
  438.      break;
  439.    case NO_RECOVERY:
  440.      err = 3;
  441.      break;
  442.    case NO_ADDRESS:
  443.      err = 4;
  444.      break;
  445.    default:
  446.      err = 5;
  447.      break;
  448.   }
  449.   SOCK_ERROR(em, errmsg[err]);
  450. }
  451. #else // !_WIN32
  452. /* Use the native UNIX call */
  453. void sockinetaddr::herror(const char* em) const
  454. {
  455. #ifdef _decunix_
  456.   if (errno)
  457.     Error(500, L"%s%S%s%d%s%S%s%d", L"class", em, L"h_errno", h_errno,
  458.   L"errnoStr", strerror(errno), L"errno", errno);
  459.   else
  460.     Error(500, L"%s%S%s%d", L"class", em, L"h_errno", h_errno);
  461. #else
  462.   SOCK_ERROR(em, hstrerror(h_errno));
  463. #endif
  464. }
  465. #endif // !_WIN32