SimpleSocket.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /*---------------------------------------------------------------------------*/
  2. /* */
  3. /* SimpleSocket.h - Simple Socket base class decleration. */
  4. /* */
  5. /* Author : Mark Carrier (mark@carrierlabs.com) */
  6. /* */
  7. /*---------------------------------------------------------------------------*/
  8. /* Copyright (c) 2007-2009 CarrierLabs, LLC. All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. *
  17. * 2. Redistributions in binary form must reproduce the above copyright
  18. * notice, this list of conditions and the following disclaimer in
  19. * the documentation and/or other materials provided with the
  20. * distribution.
  21. *
  22. * 3. The name of the author may not be used to endorse or promote products
  23. * derived from this software without specific prior written permission.
  24. *
  25. * 4. The name "CarrierLabs" must not be used to
  26. * endorse or promote products derived from this software without
  27. * prior written permission. For written permission, please contact
  28. * mark@carrierlabs.com.
  29. *
  30. * THIS SOFTWARE IS PROVIDED BY MARK CARRIER ``AS IS'' AND ANY
  31. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  33. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MARK CARRIER OR
  34. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41. * OF THE POSSIBILITY OF SUCH DAMAGE.
  42. *----------------------------------------------------------------------------*/
  43. #ifndef __SOCKET_H__
  44. #define __SOCKET_H__
  45. #include <sys/stat.h>
  46. #include <stdlib.h>
  47. #include <stdio.h>
  48. #include <stdarg.h>
  49. #include <errno.h>
  50. #if defined(_LINUX) || defined (_DARWIN)
  51. #include <sys/socket.h>
  52. #include <netinet/in.h>
  53. #include <arpa/inet.h>
  54. #include <netinet/tcp.h>
  55. #include <netinet/ip.h>
  56. #include <netdb.h>
  57. #endif
  58. #ifdef _LINUX
  59. #include <linux/if_packet.h>
  60. #include <linux/if_ether.h>
  61. #include <linux/if.h>
  62. #include <sys/sendfile.h>
  63. #endif
  64. #ifdef _DARWIN
  65. #include <net/if.h>
  66. #endif
  67. #if defined(_LINUX) || defined (_DARWIN)
  68. #include <sys/time.h>
  69. #include <sys/uio.h>
  70. #include <unistd.h>
  71. #include <fcntl.h>
  72. #endif
  73. #ifdef _WIN32
  74. #include <io.h>
  75. #include <winsock2.h>
  76. #include <ws2tcpip.h>
  77. #endif // _WIN32
  78. #define IPTOS_LOWDELAY 0x10
  79. #include "Host.h"
  80. #include "StatTimer.h"
  81. //-----------------------------------------------------------------------------
  82. // General class macro definitions and typedefs
  83. //-----------------------------------------------------------------------------
  84. #ifndef INVALID_SOCKET
  85. #define INVALID_SOCKET ~(0)
  86. #endif
  87. #define SOCKET_SENDFILE_BLOCKSIZE 8192
  88. /// Provides a platform independent class to for socket development.
  89. /// This class is designed to abstract socket communication development in a
  90. /// platform independent manner.
  91. /// - Socket types
  92. /// -# CActiveSocket Class
  93. /// -# CPassiveSocket Class
  94. class EXPORT CSimpleSocket {
  95. public:
  96. /// Defines the three possible states for shuting down a socket.
  97. typedef enum
  98. {
  99. Receives = SHUT_RD, ///< Shutdown passive socket.
  100. Sends = SHUT_WR, ///< Shutdown active socket.
  101. Both = SHUT_RDWR ///< Shutdown both active and passive sockets.
  102. } CShutdownMode;
  103. /// Defines the socket types defined by CSimpleSocket class.
  104. typedef enum
  105. {
  106. SocketTypeInvalid, ///< Invalid socket type.
  107. SocketTypeTcp, ///< Defines socket as TCP socket.
  108. SocketTypeUdp, ///< Defines socket as UDP socket.
  109. SocketTypeTcp6, ///< Defines socket as IPv6 TCP socket.
  110. SocketTypeUdp6, ///< Defines socket as IPv6 UDP socket.
  111. SocketTypeRaw ///< Provides raw network protocol access.
  112. } CSocketType;
  113. /// Defines all error codes handled by the CSimpleSocket class.
  114. typedef enum
  115. {
  116. SocketError = -1, ///< Generic socket error translates to error below.
  117. SocketSuccess = 0, ///< No socket error.
  118. SocketInvalidSocket, ///< Invalid socket handle.
  119. SocketInvalidAddress, ///< Invalid destination address specified.
  120. SocketInvalidPort, ///< Invalid destination port specified.
  121. SocketConnectionRefused, ///< No server is listening at remote address.
  122. SocketTimedout, ///< Timed out while attempting operation.
  123. SocketEwouldblock, ///< Operation would block if socket were blocking.
  124. SocketNotconnected, ///< Currently not connected.
  125. SocketEinprogress, ///< Socket is non-blocking and the connection cannot be completed immediately
  126. SocketInterrupted, ///< Call was interrupted by a signal that was caught before a valid connection arrived.
  127. SocketConnectionAborted, ///< The connection has been aborted.
  128. SocketProtocolError, ///< Invalid protocol for operation.
  129. SocketFirewallError, ///< Firewall rules forbid connection.
  130. SocketInvalidSocketBuffer, ///< The receive buffer point outside the process's address space.
  131. SocketConnectionReset, ///< Connection was forcibly closed by the remote host.
  132. SocketAddressInUse, ///< Address already in use.
  133. SocketInvalidPointer, ///< Pointer type supplied as argument is invalid.
  134. SocketEunknown ///< Unknown error please report to mark@carrierlabs.com
  135. } CSocketError;
  136. public:
  137. CSimpleSocket(CSocketType type = SocketTypeTcp);
  138. CSimpleSocket(CSimpleSocket &socket);
  139. virtual ~CSimpleSocket()
  140. {
  141. if (m_pBuffer != NULL)
  142. {
  143. delete [] m_pBuffer;
  144. m_pBuffer = NULL;
  145. }
  146. };
  147. /// Initialize instance of CSocket. This method MUST be called before an
  148. /// object can be used. Errors : CSocket::SocketProtocolError,
  149. /// CSocket::SocketInvalidSocket,
  150. /// @return true if properly initialized.
  151. virtual bool Initialize(void);
  152. /// Close socket
  153. /// @return true if successfully closed otherwise returns false.
  154. virtual bool Close(void);
  155. /// Shutdown shut down socket send and receive operations
  156. /// CShutdownMode::Receives - Disables further receive operations.
  157. /// CShutdownMode::Sends - Disables further send operations.
  158. /// CShutdownBoth:: - Disables further send and receive operations.
  159. /// @param nShutdown specifies the type of shutdown.
  160. /// @return true if successfully shutdown otherwise returns false.
  161. virtual bool Shutdown(CShutdownMode nShutdown);
  162. /// Examine the socket descriptor sets currently owned by the instance of
  163. /// the socket class (the readfds, writefds, and errorfds parameters) to
  164. /// see whether some of their descriptors are ready for reading, are ready
  165. /// for writing, or have an exceptional condition pending, respectively.
  166. /// Block until an event happens on the specified file descriptors.
  167. /// @return true if socket has data ready, or false if not ready or timed out.
  168. virtual bool Select(void) {
  169. return Select(0,0);
  170. };
  171. /// Examine the socket descriptor sets currently owned by the instance of
  172. /// the socket class (the readfds, writefds, and errorfds parameters) to
  173. /// see whether some of their descriptors are ready for reading, are ready
  174. /// for writing, or have an exceptional condition pending, respectively.
  175. /// @param nTimeoutSec timeout in seconds for select.
  176. /// @param nTimeoutUSec timeout in micro seconds for select.
  177. /// @return true if socket has data ready, or false if not ready or timed out.
  178. virtual bool Select(int32 nTimeoutSec, int32 nTimeoutUSec);
  179. /// Does the current instance of the socket object contain a valid socket
  180. /// descriptor.
  181. /// @return true if the socket object contains a valid socket descriptor.
  182. virtual bool IsSocketValid(void) {
  183. return (m_socket != SocketError);
  184. };
  185. /// Provides a standard error code for cross platform development by
  186. /// mapping the operating system error to an error defined by the CSocket
  187. /// class.
  188. void TranslateSocketError(void);
  189. /// Returns a human-readable description of the given error code
  190. /// or the last error code of a socket
  191. static const char *DescribeError(CSocketError err);
  192. inline const char *DescribeError() {
  193. return DescribeError(m_socketErrno);
  194. };
  195. /// Attempts to receive a block of data on an established connection.
  196. /// @param nMaxBytes maximum number of bytes to receive.
  197. /// @param pBuffer, memory where to receive the data,
  198. /// NULL receives to internal buffer returned with GetData()
  199. /// Non-NULL receives directly there, but GetData() will return WRONG ptr!
  200. /// @return number of bytes actually received.
  201. /// @return of zero means the connection has been shutdown on the other side.
  202. /// @return of -1 means that an error has occurred.
  203. virtual int32 Receive(int32 nMaxBytes = 1, uint8 * pBuffer = 0);
  204. /// Attempts to send a block of data on an established connection.
  205. /// @param pBuf block of data to be sent.
  206. /// @param bytesToSend size of data block to be sent.
  207. /// @return number of bytes actually sent.
  208. /// @return of zero means the connection has been shutdown on the other side.
  209. /// @return of -1 means that an error has occurred.
  210. virtual int32 Send(const uint8 *pBuf, size_t bytesToSend);
  211. /// Attempts to send at most nNumItem blocks described by sendVector
  212. /// to the socket descriptor associated with the socket object.
  213. /// @param sendVector pointer to an array of iovec structures
  214. /// @param nNumItems number of items in the vector to process
  215. /// <br>\b NOTE: Buffers are processed in the order specified.
  216. /// @return number of bytes actually sent, return of zero means the
  217. /// connection has been shutdown on the other side, and a return of -1
  218. /// means that an error has occurred.
  219. virtual int32 Send(const struct iovec *sendVector, int32 nNumItems);
  220. /// Copies data between one file descriptor and another.
  221. /// On some systems this copying is done within the kernel, and thus is
  222. /// more efficient than the combination of CSimpleSocket::Send and
  223. /// CSimpleSocket::Receive, which would require transferring data to and
  224. /// from user space.
  225. /// <br>\b Note: This is available on all implementations, but the kernel
  226. /// implementation is only available on Unix type systems.
  227. /// @param nOutFd descriptor opened for writing.
  228. /// @param nInFd descriptor opened for reading.
  229. /// @param pOffset from which to start reading data from input file.
  230. /// @param nCount number of bytes to copy between file descriptors.
  231. /// @return number of bytes written to the out socket descriptor.
  232. virtual int32 SendFile(int32 nOutFd, int32 nInFd, off_t *pOffset, int32 nCount);
  233. /// Returns blocking/non-blocking state of socket.
  234. /// @return true if the socket is non-blocking, else return false.
  235. bool IsNonblocking(void) {
  236. return (m_bIsBlocking == false);
  237. };
  238. /// Set the socket to blocking.
  239. /// @return true if successful set to blocking, else return false;
  240. bool SetBlocking(void);
  241. /// Set the socket as non-blocking.
  242. /// @return true if successful set to non-blocking, else return false;
  243. bool SetNonblocking(void);
  244. /// Get a pointer to internal receive buffer. The user MUST not free this
  245. /// pointer when finished. This memory is managed internally by the CSocket
  246. /// class.
  247. /// @return pointer to data if valid, else returns NULL.
  248. uint8 *GetData(void) {
  249. return m_pBuffer;
  250. };
  251. /// Returns the number of bytes received on the last call to
  252. /// CSocket::Receive().
  253. /// @return number of bytes received.
  254. int32 GetBytesReceived(void) {
  255. return m_nBytesReceived;
  256. };
  257. /// Returns the number of bytes sent on the last call to
  258. /// CSocket::Send().
  259. /// @return number of bytes sent.
  260. int32 GetBytesSent(void) {
  261. return m_nBytesSent;
  262. };
  263. /// Controls the actions taken when CSimpleSocket::Close is executed on a
  264. /// socket object that has unsent data. The default value for this option
  265. /// is \b off.
  266. /// - Following are the three possible scenarios.
  267. /// -# \b bEnable is false, CSimpleSocket::Close returns immediately, but
  268. /// any unset data is transmitted (after CSimpleSocket::Close returns)
  269. /// -# \b bEnable is true and \b nTime is zero, CSimpleSocket::Close return
  270. /// immediately and any unsent data is discarded.
  271. /// -# \b bEnable is true and \b nTime is nonzero, CSimpleSocket::Close does
  272. /// not return until all unsent data is transmitted (or the connection is
  273. /// Closed by the remote system).
  274. /// <br><p>
  275. /// @param bEnable true to enable option false to disable option.
  276. /// @param nTime time in seconds to linger.
  277. /// @return true if option successfully set
  278. bool SetOptionLinger(bool bEnable, uint16 nTime);
  279. /// Tells the kernel that even if this port is busy (in the TIME_WAIT state),
  280. /// go ahead and reuse it anyway. If it is busy, but with another state,
  281. /// you will still get an address already in use error.
  282. /// @return true if option successfully set
  283. bool SetOptionReuseAddr();
  284. /// Gets the timeout value that specifies the maximum number of seconds a
  285. /// call to CSimpleSocket::Open waits until it completes.
  286. /// @return the length of time in seconds
  287. int32 GetConnectTimeoutSec(void) {
  288. return m_stConnectTimeout.tv_sec;
  289. };
  290. /// Gets the timeout value that specifies the maximum number of microseconds
  291. /// a call to CSimpleSocket::Open waits until it completes.
  292. /// @return the length of time in microseconds
  293. int32 GetConnectTimeoutUSec(void) {
  294. return m_stConnectTimeout.tv_usec;
  295. };
  296. /// Sets the timeout value that specifies the maximum amount of time a call
  297. /// to CSimpleSocket::Receive waits until it completes. Use the method
  298. /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait.
  299. /// If a call to CSimpleSocket::Receive has blocked for the specified length of
  300. /// time without receiving additional data, it returns with a partial count
  301. /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data
  302. /// were received.
  303. /// @param nConnectTimeoutSec of timeout in seconds.
  304. /// @param nConnectTimeoutUsec of timeout in microseconds.
  305. /// @return true if socket connection timeout was successfully set.
  306. void SetConnectTimeout(int32 nConnectTimeoutSec, int32 nConnectTimeoutUsec = 0)
  307. {
  308. m_stConnectTimeout.tv_sec = nConnectTimeoutSec;
  309. m_stConnectTimeout.tv_usec = nConnectTimeoutUsec;
  310. };
  311. /// Gets the timeout value that specifies the maximum number of seconds a
  312. /// a call to CSimpleSocket::Receive waits until it completes.
  313. /// @return the length of time in seconds
  314. int32 GetReceiveTimeoutSec(void) {
  315. return m_stRecvTimeout.tv_sec;
  316. };
  317. /// Gets the timeout value that specifies the maximum number of microseconds
  318. /// a call to CSimpleSocket::Receive waits until it completes.
  319. /// @return the length of time in microseconds
  320. int32 GetReceiveTimeoutUSec(void) {
  321. return m_stRecvTimeout.tv_usec;
  322. };
  323. /// Sets the timeout value that specifies the maximum amount of time a call
  324. /// to CSimpleSocket::Receive waits until it completes. Use the method
  325. /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait.
  326. /// If a call to CSimpleSocket::Receive has blocked for the specified length of
  327. /// time without receiving additional data, it returns with a partial count
  328. /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data
  329. /// were received.
  330. /// @param nRecvTimeoutSec of timeout in seconds.
  331. /// @param nRecvTimeoutUsec of timeout in microseconds.
  332. /// @return true if socket timeout was successfully set.
  333. bool SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutUsec = 0);
  334. /// Enable/disable multicast for a socket. This options is only valid for
  335. /// socket descriptors of type CSimpleSocket::SocketTypeUdp.
  336. /// @return true if multicast was enabled or false if socket type is not
  337. /// CSimpleSocket::SocketTypeUdp and the error will be set to
  338. /// CSimpleSocket::SocketProtocolError
  339. bool SetMulticast(bool bEnable, uint8 multicastTTL = 1);
  340. /// Return true if socket is multicast or false is socket is unicast
  341. /// @return true if multicast is enabled
  342. bool GetMulticast() {
  343. return m_bIsMulticast;
  344. };
  345. /// Bind socket to a specific interface when using multicast.
  346. /// @return true if successfully bound to interface
  347. bool BindInterface(const char *pInterface);
  348. /// Gets the timeout value that specifies the maximum number of seconds a
  349. /// a call to CSimpleSocket::Send waits until it completes.
  350. /// @return the length of time in seconds
  351. int32 GetSendTimeoutSec(void) {
  352. return m_stSendTimeout.tv_sec;
  353. };
  354. /// Gets the timeout value that specifies the maximum number of microseconds
  355. /// a call to CSimpleSocket::Send waits until it completes.
  356. /// @return the length of time in microseconds
  357. int32 GetSendTimeoutUSec(void) {
  358. return m_stSendTimeout.tv_usec;
  359. };
  360. /// Gets the timeout value that specifies the maximum amount of time a call
  361. /// to CSimpleSocket::Send waits until it completes.
  362. /// @return the length of time in seconds
  363. bool SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec = 0);
  364. /// Returns the last error that occured for the instace of the CSimpleSocket
  365. /// instance. This method should be called immediately to retrieve the
  366. /// error code for the failing mehtod call.
  367. /// @return last error that occured.
  368. CSocketError GetSocketError(void) {
  369. return m_socketErrno;
  370. };
  371. /// Get the total time the of the last operation in milliseconds.
  372. /// @return number of milliseconds of last operation.
  373. uint32 GetTotalTimeMs() {
  374. return m_timer.GetMilliSeconds();
  375. };
  376. /// Get the total time the of the last operation in microseconds.
  377. /// @return number of microseconds or last operation.
  378. uint32 GetTotalTimeUsec() {
  379. return m_timer.GetMicroSeconds();
  380. };
  381. /// Return Differentiated Services Code Point (DSCP) value currently set on the socket object.
  382. /// @return DSCP for current socket object.
  383. /// <br><br> \b NOTE: Windows special notes http://support.microsoft.com/kb/248611.
  384. int GetSocketDscp(void);
  385. /// Set Differentiated Services Code Point (DSCP) for socket object.
  386. /// @param nDscp value of TOS setting which will be converted to DSCP
  387. /// @return true if DSCP value was properly set
  388. /// <br><br> \b NOTE: Windows special notes http://support.microsoft.com/kb/248611.
  389. bool SetSocketDscp(int nDscp);
  390. /// Return socket descriptor
  391. /// @return socket descriptor which is a signed 32 bit integer.
  392. SOCKET GetSocketDescriptor() {
  393. return m_socket;
  394. };
  395. /// Return socket descriptor
  396. /// @return socket descriptor which is a signed 32 bit integer.
  397. CSocketType GetSocketType() {
  398. return m_nSocketType;
  399. };
  400. /// Returns clients Internet host address as a string in standard numbers-and-dots notation.
  401. /// @return NULL if invalid
  402. const char *GetClientAddr() {
  403. return inet_ntoa(m_stClientSockaddr.sin_addr);
  404. };
  405. /// Returns the port number on which the client is connected.
  406. /// @return client port number.
  407. uint16 GetClientPort() {
  408. return m_stClientSockaddr.sin_port;
  409. };
  410. /// Returns server Internet host address as a string in standard numbers-and-dots notation.
  411. /// @return NULL if invalid
  412. const char *GetServerAddr() {
  413. return inet_ntoa(m_stServerSockaddr.sin_addr);
  414. };
  415. /// Returns the port number on which the server is connected.
  416. /// @return server port number.
  417. uint16 GetServerPort() {
  418. return ntohs(m_stServerSockaddr.sin_port);
  419. };
  420. /// Get the TCP receive buffer window size for the current socket object.
  421. /// <br><br>\b NOTE: Linux will set the receive buffer to twice the value passed.
  422. /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful.
  423. uint32 GetReceiveWindowSize() {
  424. return GetWindowSize(SO_RCVBUF);
  425. };
  426. /// Get the TCP send buffer window size for the current socket object.
  427. /// <br><br>\b NOTE: Linux will set the send buffer to twice the value passed.
  428. /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful.
  429. uint32 GetSendWindowSize() {
  430. return GetWindowSize(SO_SNDBUF);
  431. };
  432. /// Set the TCP receive buffer window size for the current socket object.
  433. /// <br><br>\b NOTE: Linux will set the receive buffer to twice the value passed.
  434. /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful.
  435. uint32 SetReceiveWindowSize(uint32 nWindowSize) {
  436. return SetWindowSize(SO_RCVBUF, nWindowSize);
  437. };
  438. /// Set the TCP send buffer window size for the current socket object.
  439. /// <br><br>\b NOTE: Linux will set the send buffer to twice the value passed.
  440. /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful.
  441. uint32 SetSendWindowSize(uint32 nWindowSize) {
  442. return SetWindowSize(SO_SNDBUF, nWindowSize);
  443. };
  444. /// Disable the Nagle algorithm (Set TCP_NODELAY to true)
  445. /// @return false if failed to set socket option otherwise return true;
  446. bool DisableNagleAlgoritm();
  447. /// Enable the Nagle algorithm (Set TCP_NODELAY to false)
  448. /// @return false if failed to set socket option otherwise return true;
  449. bool EnableNagleAlgoritm();
  450. protected:
  451. /// Set internal socket error to that specified error
  452. /// @param error type of error
  453. void SetSocketError(CSimpleSocket::CSocketError error) {
  454. m_socketErrno = error;
  455. };
  456. /// Set object socket handle to that specified as parameter
  457. /// @param socket value of socket descriptor
  458. void SetSocketHandle(SOCKET socket) {
  459. m_socket = socket;
  460. };
  461. private:
  462. /// Generic function used to get the send/receive window size
  463. /// @return zero on failure else the number of bytes of the TCP window size if successful.
  464. uint32 GetWindowSize(uint32 nOptionName);
  465. /// Generic function used to set the send/receive window size
  466. /// @return zero on failure else the number of bytes of the TCP window size if successful.
  467. uint32 SetWindowSize(uint32 nOptionName, uint32 nWindowSize);
  468. /// Attempts to send at most nNumItem blocks described by sendVector
  469. /// to the socket descriptor associated with the socket object.
  470. /// @param sendVector pointer to an array of iovec structures
  471. /// @param nNumItems number of items in the vector to process
  472. /// <br>\b Note: This implementation is for systems that don't natively
  473. /// support this functionality.
  474. /// @return number of bytes actually sent, return of zero means the
  475. /// connection has been shutdown on the other side, and a return of -1
  476. /// means that an error has occurred.
  477. int32 Writev(const struct iovec *pVector, size_t nCount);
  478. /// Flush the socket descriptor owned by the object.
  479. /// @return true data was successfully sent, else return false;
  480. bool Flush();
  481. CSimpleSocket *operator=(CSimpleSocket &socket);
  482. protected:
  483. SOCKET m_socket; /// socket handle
  484. CSocketError m_socketErrno; /// number of last error
  485. uint8 *m_pBuffer; /// internal send/receive buffer
  486. int32 m_nBufferSize; /// size of internal send/receive buffer
  487. int32 m_nSocketDomain; /// socket type PF_INET, PF_INET6
  488. CSocketType m_nSocketType; /// socket type - UDP, TCP or RAW
  489. int32 m_nBytesReceived; /// number of bytes received
  490. int32 m_nBytesSent; /// number of bytes sent
  491. uint32 m_nFlags; /// socket flags
  492. bool m_bIsBlocking; /// is socket blocking
  493. bool m_bIsMulticast; /// is the UDP socket multicast;
  494. struct timeval m_stConnectTimeout; /// connection timeout
  495. struct timeval m_stRecvTimeout; /// receive timeout
  496. struct timeval m_stSendTimeout; /// send timeout
  497. struct sockaddr_in m_stServerSockaddr; /// server address
  498. struct sockaddr_in m_stClientSockaddr; /// client address
  499. struct sockaddr_in m_stMulticastGroup; /// multicast group to bind to
  500. struct linger m_stLinger; /// linger flag
  501. CStatTimer m_timer; /// internal statistics.
  502. #ifdef WIN32
  503. WSADATA m_hWSAData; /// Windows
  504. #endif
  505. fd_set m_writeFds; /// write file descriptor set
  506. fd_set m_readFds; /// read file descriptor set
  507. fd_set m_errorFds; /// error file descriptor set
  508. };
  509. #endif /* __SOCKET_H__ */