sockio.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #ifndef _SOCKIO_H_
  36. #define _SOCKIO_H_
  37. class TCPIO;
  38. #ifdef _SOLARIS
  39. #include <sys/systeminfo.h>
  40. #include <sys/filio.h>
  41. #endif /* _SOLARIS */
  42. #include <errno.h>
  43. #include <sys/ioctl.h>
  44. #include <unistd.h>
  45. #include <sys/types.h>
  46. #include <sys/socket.h>
  47. #include <netinet/in.h>
  48. #ifndef _BEOS
  49. #include <arpa/inet.h>
  50. #endif
  51. #ifndef _VXWORKS
  52. #include <netdb.h>
  53. #else
  54. #include <ioLib.h>
  55. #ifndef fcntl
  56. #define fcntl ioctl
  57. #endif
  58. #include <sockLib.h>
  59. #endif
  60. #include <string.h>
  61. #include "hxassert.h"
  62. #include "hxstrutl.h"
  63. #include "asyncio.h"
  64. #if defined PAULM_SOCKTIMING 
  65. #include "sockettimer.h"
  66. extern SocketTimer g_SocketTimer;
  67. #endif
  68. #if defined (_AIX42)
  69. #define HX_SOCKLEN_T size_t
  70. #elif defined(_AIX43) || defined(_FREEBSD5) || defined(_FREEBSD4) || defined(_OPENBSD) ||defined(_NETBSD) || defined(_LINUX) || (defined (__GNUC__) && defined(_SOLARIS))
  71. #define HX_SOCKLEN_T socklen_t
  72. #else
  73. #define HX_SOCKLEN_T int
  74. #endif
  75. #ifndef HX_SOCKADDR_T
  76. #if defined _HPUX
  77. #define HX_SOCKADDR_T void
  78. #else
  79. #define HX_SOCKADDR_T sockaddr
  80. #endif
  81. #endif
  82. #ifndef INADDR_NONE
  83. #define INADDR_NONE (-1)
  84. #endif
  85. #include <sys/uio.h>
  86. #include <unistd.h>
  87. #define HX_IOVEC struct iovec
  88. #ifdef IOV_MAX
  89. #define MAX_IOVECTORS IOV_MAX
  90. #else
  91. #define MAX_IOVECTORS 1000
  92. #endif
  93. class SocketIO: public AsyncIO
  94. {
  95. public:
  96.     friend class TCPIO;
  97.     friend class UDPIO;
  98. SocketIO();
  99.     virtual      ~SocketIO();
  100.     static INT32 create_address(struct sockaddr_in& addr, char* host,
  101.        INT16 port);
  102.     INT32               init(INT32 type, BOOL do_block=TRUE,
  103.                                BOOL reuse_addr=TRUE, BOOL reuse_port=FALSE);
  104.     INT32 init(INT32 type, UINT32 local_addr, INT16 port, 
  105.      BOOL do_block=TRUE, 
  106.      BOOL reuse_addr=TRUE, BOOL reuse_port=FALSE);
  107.     virtual INT32 listen(INT32 backlog);
  108.     virtual INT32 connect(sockaddr_in *addr);
  109.     virtual INT32 bind(sockaddr_in*);
  110.     virtual INT32 blocking();
  111.     virtual INT32 nonblocking();
  112.     virtual INT32 getsockname(sockaddr_in* addr, INT32* addr_len);
  113.     virtual INT32 close();
  114.     virtual INT32 read(void* buf, INT32 size);
  115.     virtual INT32 write(const void* buf, INT32 size);
  116.     virtual off_t seek(off_t off, INT32 whence);
  117.     virtual INT16 port();
  118.     virtual INT32 disable();
  119.     virtual INT32 reuse_port(BOOL enable);
  120.     virtual INT32 reuse_addr(BOOL enable);
  121.     virtual INT32 error();
  122.     virtual INT32 flags();
  123.     virtual int fd();
  124.     virtual void fd(int s);
  125. #if defined PAULM_SOCKTIMING 
  126.     void fd(int s, int c);
  127. #endif
  128.     virtual off_t file_size();
  129.     static const UINT32 MAX_HOSTNAME_LEN;
  130.     static int gethostname(char* name, int count);
  131. protected:
  132. SocketIO(int conn);
  133.     INT32 err;
  134.     int sock;
  135.     INT32 _flags;
  136. };
  137. inline
  138. SocketIO::SocketIO()
  139. {
  140.     _flags = O_RDWR;
  141.     sock = -1;
  142.     err = 0;
  143. }
  144. inline
  145. SocketIO::SocketIO(int conn)
  146. {
  147.     _flags = O_RDWR;
  148.     sock = conn;
  149.     err = 0;
  150. }
  151. inline INT32
  152. SocketIO::error()
  153. {
  154.     return err;
  155. }
  156. inline INT32
  157. SocketIO::flags()
  158. {
  159.     return _flags;
  160. }
  161. inline int
  162. SocketIO::fd()
  163. {
  164.     return sock;
  165. }
  166. inline void
  167. SocketIO::fd(int s)
  168. {
  169. #if defined PAULM_SOCKTIMING 
  170.     sockaddr_in a;
  171.     int size = sizeof(a);
  172.     if (!::getsockname(s, (sockaddr*)&a, &size))
  173.     {
  174. g_SocketTimer.Add(s, ntohs(a.sin_port));
  175.     }
  176. #endif
  177.     sock = s;
  178. }
  179. #if defined PAULM_SOCKTIMING 
  180. inline void
  181. SocketIO::fd(int s, int c)
  182. {
  183.     sockaddr_in a;
  184.     int size = sizeof(a);
  185.     if (!::getsockname(s, (sockaddr*)&a, &size))
  186.     {
  187. g_SocketTimer.Add(s, ntohs(a.sin_port), c);
  188.     }
  189.     sock  = s;
  190. }
  191. #endif
  192. inline INT32
  193. SocketIO::disable()
  194. {
  195.     sock = -2;
  196.     return 0;
  197. }
  198. inline INT32
  199. SocketIO::close() 
  200. {
  201.     if (sock < 0)
  202.     {
  203. return 0;
  204.     }
  205. #if defined PAULM_SOCKTIMING 
  206.     g_SocketTimer.Remove(sock);
  207. #endif
  208.     INT32 ret = ::close(sock);
  209.     sock = -1;
  210.     if (ret < 0)
  211. err = errno;
  212.     return ret;
  213. }
  214. inline
  215. SocketIO::~SocketIO() 
  216. {
  217.     close();
  218. }
  219. inline INT32
  220. SocketIO::blocking() 
  221. {
  222. #ifdef FIONBIO
  223.     INT32 dont_block = 0;
  224.     INT32 ret = ::ioctl(sock, FIONBIO, (char*)&dont_block);
  225.     if (ret < 0)
  226. err = errno;
  227. #elif SO_NONBLOCK
  228.     char dont_block=0;
  229.     INT32 ret = ::setsockopt(sock,SOL_SOCKET,SO_NONBLOCK,&dont_block,1);
  230. #else
  231.     INT32 ret = ::fcntl(sock, F_SETFL, ::fcntl(sock, F_GETFL, 0) & ~O_NONBLOCK);
  232. #endif
  233.     return ret;
  234. }
  235. inline INT32
  236. SocketIO::nonblocking() 
  237. {
  238. #ifdef FIONBIO
  239.     INT32 dont_block = 1;
  240.     INT32 ret = ::ioctl(sock, FIONBIO, (char*)&dont_block);
  241.     if (ret < 0)
  242. err = errno;
  243. #elif SO_NONBLOCK
  244.     char dont_block=1;
  245.     INT32 ret = ::setsockopt(sock,SOL_SOCKET,SO_NONBLOCK,&dont_block,1);
  246. #else
  247.     INT32 ret = ::fcntl(sock, F_SETFL, ::fcntl(sock, F_GETFL, 0) | O_NONBLOCK);
  248. #endif
  249.     return ret;
  250. }
  251. inline INT32
  252. SocketIO::getsockname(sockaddr_in* addr, INT32* addr_len)
  253. {
  254.     if (sock < 0)
  255.     {
  256. err = EBADF;
  257. return -1;
  258.     }
  259.     HX_SOCKLEN_T temp_addr = *addr_len;
  260.     int ret = ::getsockname(sock, (HX_SOCKADDR_T*)addr, (HX_SOCKLEN_T *)&temp_addr);
  261.     *addr_len = temp_addr;
  262. #ifdef _LINUX
  263.     if (!ret && ((sockaddr_in*)addr)->sin_family == AF_UNIX) 
  264.     { 
  265. ((sockaddr_in*)addr)->sin_addr.s_addr = inet_addr("127.0.0.1"); 
  266.     }
  267. #elif _SUN
  268.     if (!ret && !((sockaddr_in*)addr)->sin_addr.s_addr)
  269.     {
  270. ((sockaddr_in*)addr)->sin_addr.s_addr = inet_addr("127.0.0.1");
  271.     }
  272. #endif /* _LINUX */
  273.     if (ret < 0)
  274. err = errno;
  275.     return ret;
  276. }
  277. inline INT32
  278. SocketIO::listen(INT32 backlog) 
  279. {
  280.     if (sock < 0)
  281.     {
  282. err = EBADF;
  283. return -1;
  284.     }
  285.     INT32 ret = ::listen(sock, backlog);
  286.     if (ret < 0)
  287. err = errno;
  288.     return ret;
  289. }
  290. inline INT32
  291. SocketIO::bind(sockaddr_in* addr) 
  292. {
  293.     if (sock < 0)
  294.     {
  295. err = EBADF;
  296. return -1;
  297.     }
  298.     INT32 ret = ::bind(sock, (HX_SOCKADDR_T*)addr, sizeof *addr);
  299.     if (ret < 0)
  300. err = errno;
  301.     return ret;
  302. }
  303. inline INT32
  304. SocketIO::connect(sockaddr_in* addr) 
  305. {
  306.     if (sock < 0)
  307.     {
  308. err = EBADF;
  309. return -1;
  310.     }
  311.     INT32 ret = ::connect(sock, (HX_SOCKADDR_T*)addr, sizeof *addr);
  312.     if (ret < 0)
  313. err = errno;
  314.     return ret;
  315. }
  316. inline INT32
  317. SocketIO::read(void * buf, INT32 len) 
  318. {
  319.     if (sock < 0)
  320.     {
  321. err = EBADF;
  322. return -1;
  323.     }
  324.     INT32 ret = ::recv(sock, (char*)buf, len, 0);
  325.     err = errno;
  326.     while (ret < 0 && err == EINTR)
  327.     {
  328. ret = ::recv(sock, (char*)buf, len, 0);
  329. err = errno;
  330.     }
  331.     return ret;
  332. }
  333. inline INT32
  334. SocketIO::write(const void * buf, INT32 len) 
  335. {    
  336.     if (sock < 0)
  337.     {
  338. err = EBADF;
  339. return -1;
  340.     }
  341.     INT32 ret = ::send(sock, (const char *)buf, len, 0);
  342.     if (ret < 0)
  343. err = errno;
  344. #if defined SOLARIS2_4
  345.     if (err == EINVAL)    /* This is a hack to get solaris 2.4 to work */
  346.     {
  347. err = 0;
  348. ret = 0;
  349.     }
  350. #endif
  351.     return ret;
  352. }
  353. inline INT16
  354. SocketIO::port()
  355. {
  356.     sockaddr_in addr;
  357.     INT32 addr_len = sizeof addr;
  358.     memset(&addr, 0, addr_len);
  359.     INT32 ret = getsockname(&addr, &addr_len);
  360.     return (ret < 0) ? ret : ntohs(addr.sin_port);
  361. }
  362. inline INT32
  363. SocketIO::reuse_port(BOOL enable)
  364. {
  365. #if defined(SO_REUSEPORT) && !defined(__QNXNTO__)
  366.     if (sock < 0)
  367.     {
  368. err = EBADF;
  369. return -1;
  370.     }
  371.     INT32  ret;
  372.     int  opt_val = 0;
  373.     if (enable)
  374.     {
  375. opt_val = 1;
  376.     }
  377.     ret = ::setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char*) &opt_val,
  378.        sizeof (int));
  379.     if (ret < 0)
  380.     {
  381. err = errno;
  382.     }
  383.     return ret;
  384. #else
  385.     return 0;
  386. #endif
  387. }
  388. inline INT32
  389. SocketIO::reuse_addr(BOOL enable)
  390.     if (sock < 0)
  391.     {
  392. err = EBADF;
  393. return -1;
  394.     }
  395.     INT32 ret;
  396.     int   opt_val = 0;
  397.     if (enable)
  398.     {
  399. opt_val = 1;
  400.     }
  401.     ret = ::setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &opt_val,
  402.        sizeof (int));
  403.     if (ret < 0)
  404.     {
  405. err = errno;
  406.     }
  407.     return ret;
  408. }
  409. inline off_t
  410. SocketIO::seek(off_t off, INT32 whence)
  411. {
  412.     ASSERT(FALSE);
  413.     return -1;
  414. }
  415. inline int
  416. SocketIO::gethostname(char* name, int count)
  417. {
  418.     LONG32 result;
  419. #ifdef _SOLARIS
  420.     result = sysinfo(SI_HOSTNAME, name, count);
  421. #elif defined _VXWORKS
  422.     SafeStrCpy(name,  "VXWORKS", count);
  423. #else
  424.     result = ::gethostname(name, count);
  425. #endif /* _SOLARIS */
  426.     if (result < 0)
  427.     {
  428. return errno;
  429.     }
  430.     return 0;
  431. }
  432. inline off_t
  433. SocketIO::file_size()
  434. {
  435.     ASSERT(0);
  436.     return -1;
  437. }
  438. #endif /* _SOCKIO_H_ */