SocketImpl.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. //
  2. // SocketImpl.h
  3. //
  4. // $Id: //poco/Main/Net/include/Poco/Net/SocketImpl.h#6 $
  5. //
  6. // Library: Net
  7. // Package: Sockets
  8. // Module: SocketImpl
  9. //
  10. // Definition of the SocketImpl class.
  11. //
  12. // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Net_SocketImpl_INCLUDED
  38. #define Net_SocketImpl_INCLUDED
  39. #include "Poco/Net/Net.h"
  40. #include "Poco/Net/SocketDefs.h"
  41. #include "Poco/Net/SocketAddress.h"
  42. #include "Poco/RefCountedObject.h"
  43. #include "Poco/Timespan.h"
  44. namespace Poco {
  45. namespace Net {
  46. class Net_API SocketImpl: public Poco::RefCountedObject
  47. /// This class encapsulates the Berkeley sockets API.
  48. ///
  49. /// Subclasses implement specific socket types like
  50. /// stream or datagram sockets.
  51. ///
  52. /// You should not create any instances of this class.
  53. {
  54. public:
  55. enum SelectMode
  56. {
  57. SELECT_READ = 1,
  58. SELECT_WRITE = 2,
  59. SELECT_ERROR = 4
  60. };
  61. virtual SocketImpl* acceptConnection(SocketAddress& clientAddr);
  62. /// Get the next completed connection from the
  63. /// socket's completed connection queue.
  64. ///
  65. /// If the queue is empty, waits until a connection
  66. /// request completes.
  67. ///
  68. /// Returns a new TCP socket for the connection
  69. /// with the client.
  70. ///
  71. /// The client socket's address is returned in clientAddr.
  72. virtual void connect(const SocketAddress& address);
  73. /// Initializes the socket and establishes a connection to
  74. /// the TCP server at the given address.
  75. ///
  76. /// Can also be used for UDP sockets. In this case, no
  77. /// connection is established. Instead, incoming and outgoing
  78. /// packets are restricted to the specified address.
  79. virtual void connect(const SocketAddress& address, const Poco::Timespan& timeout);
  80. /// Initializes the socket, sets the socket timeout and
  81. /// establishes a connection to the TCP server at the given address.
  82. virtual void connectNB(const SocketAddress& address);
  83. /// Initializes the socket and establishes a connection to
  84. /// the TCP server at the given address. Prior to opening the
  85. /// connection the socket is set to nonblocking mode.
  86. virtual void bind(const SocketAddress& address, bool reuseAddress = false);
  87. /// Bind a local address to the socket.
  88. ///
  89. /// This is usually only done when establishing a server
  90. /// socket. TCP clients should not bind a socket to a
  91. /// specific address.
  92. ///
  93. /// If reuseAddress is true, sets the SO_REUSEADDR
  94. /// socket option.
  95. virtual void listen(int backlog = 64);
  96. /// Puts the socket into listening state.
  97. ///
  98. /// The socket becomes a passive socket that
  99. /// can accept incoming connection requests.
  100. ///
  101. /// The backlog argument specifies the maximum
  102. /// number of connections that can be queued
  103. /// for this socket.
  104. virtual void close();
  105. /// Close the socket.
  106. virtual void shutdownReceive();
  107. /// Shuts down the receiving part of the socket connection.
  108. virtual void shutdownSend();
  109. /// Shuts down the sending part of the socket connection.
  110. virtual void shutdown();
  111. /// Shuts down both the receiving and the sending part
  112. /// of the socket connection.
  113. virtual int sendBytes(const void* buffer, int length, int flags = 0);
  114. /// Sends the contents of the given buffer through
  115. /// the socket.
  116. ///
  117. /// Returns the number of bytes sent, which may be
  118. /// less than the number of bytes specified.
  119. virtual int receiveBytes(void* buffer, int length, int flags = 0);
  120. /// Receives data from the socket and stores it
  121. /// in buffer. Up to length bytes are received.
  122. ///
  123. /// Returns the number of bytes received.
  124. virtual int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0);
  125. /// Sends the contents of the given buffer through
  126. /// the socket to the given address.
  127. ///
  128. /// Returns the number of bytes sent, which may be
  129. /// less than the number of bytes specified.
  130. virtual int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0);
  131. /// Receives data from the socket and stores it
  132. /// in buffer. Up to length bytes are received.
  133. /// Stores the address of the sender in address.
  134. ///
  135. /// Returns the number of bytes received.
  136. virtual void sendUrgent(unsigned char data);
  137. /// Sends one byte of urgent data through
  138. /// the socket.
  139. ///
  140. /// The data is sent with the MSG_OOB flag.
  141. ///
  142. /// The preferred way for a socket to receive urgent data
  143. /// is by enabling the SO_OOBINLINE option.
  144. virtual int available();
  145. /// Returns the number of bytes available that can be read
  146. /// without causing the socket to block.
  147. virtual bool poll(const Poco::Timespan& timeout, int mode);
  148. /// Determines the status of the socket, using a
  149. /// call to select().
  150. ///
  151. /// The mode argument is constructed by combining the values
  152. /// of the SelectMode enumeration.
  153. ///
  154. /// Returns true if the next operation corresponding to
  155. /// mode will not block, false otherwise.
  156. virtual void setSendBufferSize(int size);
  157. /// Sets the size of the send buffer.
  158. virtual int getSendBufferSize();
  159. /// Returns the size of the send buffer.
  160. ///
  161. /// The returned value may be different than the
  162. /// value previously set with setSendBufferSize(),
  163. /// as the system is free to adjust the value.
  164. virtual void setReceiveBufferSize(int size);
  165. /// Sets the size of the receive buffer.
  166. virtual int getReceiveBufferSize();
  167. /// Returns the size of the receive buffer.
  168. ///
  169. /// The returned value may be different than the
  170. /// value previously set with setReceiveBufferSize(),
  171. /// as the system is free to adjust the value.
  172. virtual void setSendTimeout(const Poco::Timespan& timeout);
  173. /// Sets the send timeout for the socket.
  174. virtual Poco::Timespan getSendTimeout();
  175. /// Returns the send timeout for the socket.
  176. ///
  177. /// The returned timeout may be different than the
  178. /// timeout previously set with setSendTimeout(),
  179. /// as the system is free to adjust the value.
  180. virtual void setReceiveTimeout(const Poco::Timespan& timeout);
  181. /// Sets the send timeout for the socket.
  182. ///
  183. /// On systems that do not support SO_RCVTIMEO, a
  184. /// workaround using poll() is provided.
  185. virtual Poco::Timespan getReceiveTimeout();
  186. /// Returns the receive timeout for the socket.
  187. ///
  188. /// The returned timeout may be different than the
  189. /// timeout previously set with setReceiveTimeout(),
  190. /// as the system is free to adjust the value.
  191. virtual SocketAddress address();
  192. /// Returns the IP address and port number of the socket.
  193. virtual SocketAddress peerAddress();
  194. /// Returns the IP address and port number of the peer socket.
  195. void setOption(int level, int option, int value);
  196. /// Sets the socket option specified by level and option
  197. /// to the given integer value.
  198. void setOption(int level, int option, unsigned value);
  199. /// Sets the socket option specified by level and option
  200. /// to the given integer value.
  201. void setOption(int level, int option, unsigned char value);
  202. /// Sets the socket option specified by level and option
  203. /// to the given integer value.
  204. void setOption(int level, int option, const Poco::Timespan& value);
  205. /// Sets the socket option specified by level and option
  206. /// to the given time value.
  207. void setOption(int level, int option, const IPAddress& value);
  208. /// Sets the socket option specified by level and option
  209. /// to the given time value.
  210. virtual void setRawOption(int level, int option, const void* value, poco_socklen_t length);
  211. /// Sets the socket option specified by level and option
  212. /// to the given time value.
  213. void getOption(int level, int option, int& value);
  214. /// Returns the value of the socket option
  215. /// specified by level and option.
  216. void getOption(int level, int option, unsigned& value);
  217. /// Returns the value of the socket option
  218. /// specified by level and option.
  219. void getOption(int level, int option, unsigned char& value);
  220. /// Returns the value of the socket option
  221. /// specified by level and option.
  222. void getOption(int level, int option, Poco::Timespan& value);
  223. /// Returns the value of the socket option
  224. /// specified by level and option.
  225. void getOption(int level, int option, IPAddress& value);
  226. /// Returns the value of the socket option
  227. /// specified by level and option.
  228. virtual void getRawOption(int level, int option, void* value, poco_socklen_t& length);
  229. /// Returns the value of the socket option
  230. /// specified by level and option.
  231. void setLinger(bool on, int seconds);
  232. /// Sets the value of the SO_LINGER socket option.
  233. void getLinger(bool& on, int& seconds);
  234. /// Returns the value of the SO_LINGER socket option.
  235. void setNoDelay(bool flag);
  236. /// Sets the value of the TCP_NODELAY socket option.
  237. bool getNoDelay();
  238. /// Returns the value of the TCP_NODELAY socket option.
  239. void setKeepAlive(bool flag);
  240. /// Sets the value of the SO_KEEPALIVE socket option.
  241. bool getKeepAlive();
  242. /// Returns the value of the SO_KEEPALIVE socket option.
  243. void setReuseAddress(bool flag);
  244. /// Sets the value of the SO_REUSEADDR socket option.
  245. bool getReuseAddress();
  246. /// Returns the value of the SO_REUSEADDR socket option.
  247. void setReusePort(bool flag);
  248. /// Sets the value of the SO_REUSEPORT socket option.
  249. /// Does nothing if the socket implementation does not
  250. /// support SO_REUSEPORT.
  251. bool getReusePort();
  252. /// Returns the value of the SO_REUSEPORT socket option.
  253. ///
  254. /// Returns false if the socket implementation does not
  255. /// support SO_REUSEPORT.
  256. void setOOBInline(bool flag);
  257. /// Sets the value of the SO_OOBINLINE socket option.
  258. bool getOOBInline();
  259. /// Returns the value of the SO_OOBINLINE socket option.
  260. void setBroadcast(bool flag);
  261. /// Sets the value of the SO_BROADCAST socket option.
  262. bool getBroadcast();
  263. /// Returns the value of the SO_BROADCAST socket option.
  264. virtual void setBlocking(bool flag);
  265. /// Sets the socket in blocking mode if flag is true,
  266. /// disables blocking mode if flag is false.
  267. virtual bool getBlocking() const;
  268. /// Returns the blocking mode of the socket.
  269. /// This method will only work if the blocking modes of
  270. /// the socket are changed via the setBlocking method!
  271. int socketError();
  272. /// Returns the value of the SO_ERROR socket option.
  273. poco_socket_t sockfd() const;
  274. /// Returns the socket descriptor for the
  275. /// underlying native socket.
  276. void ioctl(int request, int& arg);
  277. /// A wrapper for the ioctl system call.
  278. void ioctl(int request, void* arg);
  279. /// A wrapper for the ioctl system call.
  280. bool initialized() const;
  281. /// Returns true iff the underlying socket is initialized.
  282. protected:
  283. SocketImpl();
  284. /// Creates a SocketImpl.
  285. SocketImpl(poco_socket_t sockfd);
  286. /// Creates a SocketImpl using the given native socket.
  287. virtual ~SocketImpl();
  288. /// Destroys the SocketImpl.
  289. /// Closes the socket if it is still open.
  290. virtual void init(int af);
  291. /// Creates the underlying native socket.
  292. ///
  293. /// Subclasses must implement this method so
  294. /// that it calls initSocket() with the
  295. /// appropriate arguments.
  296. ///
  297. /// The default implementation creates a
  298. /// stream socket.
  299. void initSocket(int af, int type, int proto = 0);
  300. /// Creates the underlying native socket.
  301. ///
  302. /// The first argument, af, specifies the address family
  303. /// used by the socket, which should be either AF_INET or
  304. /// AF_INET6.
  305. ///
  306. /// The second argument, type, specifies the type of the
  307. /// socket, which can be one of SOCK_STREAM, SOCK_DGRAM
  308. /// or SOCK_RAW.
  309. ///
  310. /// The third argument, proto, is normally set to 0,
  311. /// except for raw sockets.
  312. void reset(poco_socket_t fd = POCO_INVALID_SOCKET);
  313. /// Allows subclasses to set the socket manually, iff no valid socket is set yet!
  314. static int lastError();
  315. /// Returns the last error code.
  316. static void error();
  317. /// Throws an appropriate exception for the last error.
  318. static void error(const std::string& arg);
  319. /// Throws an appropriate exception for the last error.
  320. static void error(int code);
  321. /// Throws an appropriate exception for the given error code.
  322. static void error(int code, const std::string& arg);
  323. /// Throws an appropriate exception for the given error code.
  324. private:
  325. SocketImpl(const SocketImpl&);
  326. SocketImpl& operator = (const SocketImpl&);
  327. poco_socket_t _sockfd;
  328. #if defined(POCO_BROKEN_TIMEOUTS)
  329. Poco::Timespan _recvTimeout;
  330. Poco::Timespan _sndTimeout;
  331. #endif
  332. bool _blocking;
  333. friend class Socket;
  334. friend class SecureSocketImpl;
  335. };
  336. //
  337. // inlines
  338. //
  339. inline poco_socket_t SocketImpl::sockfd() const
  340. {
  341. return _sockfd;
  342. }
  343. inline bool SocketImpl::initialized() const
  344. {
  345. return _sockfd != POCO_INVALID_SOCKET;
  346. }
  347. inline int SocketImpl::lastError()
  348. {
  349. #if defined(_WIN32)
  350. return WSAGetLastError();
  351. #else
  352. return errno;
  353. #endif
  354. }
  355. inline bool SocketImpl::getBlocking() const
  356. {
  357. return _blocking;
  358. }
  359. } } // namespace Poco::Net
  360. #endif // Net_SocketImpl_INCLUDED