lliosocket.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:11k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lliosocket.h
  3.  * @author Phoenix
  4.  * @date 2005-07-31
  5.  * @brief Declaration of files used for handling sockets and associated pipes
  6.  *
  7.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  8.  * 
  9.  * Copyright (c) 2005-2010, Linden Research, Inc.
  10.  * 
  11.  * Second Life Viewer Source Code
  12.  * The source code in this file ("Source Code") is provided by Linden Lab
  13.  * to you under the terms of the GNU General Public License, version 2.0
  14.  * ("GPL"), unless you have obtained a separate licensing agreement
  15.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  16.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  17.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  18.  * 
  19.  * There are special exceptions to the terms and conditions of the GPL as
  20.  * it is applied to this Source Code. View the full text of the exception
  21.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  22.  * online at
  23.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  24.  * 
  25.  * By copying, modifying or distributing this software, you acknowledge
  26.  * that you have read and understood your obligations described above,
  27.  * and agree to abide by those obligations.
  28.  * 
  29.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  30.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  31.  * COMPLETENESS OR PERFORMANCE.
  32.  * $/LicenseInfo$
  33.  */
  34. #ifndef LL_LLIOSOCKET_H
  35. #define LL_LLIOSOCKET_H
  36. /** 
  37.  * The socket interface provided here is a simple wraper around apr
  38.  * sockets, with a pipe source and sink to read and write off of the
  39.  * socket. Every socket only performs non-blocking operations except
  40.  * the server socket which only performs blocking operations when an
  41.  * OS poll indicates it will not block.
  42.  */
  43. #include "lliopipe.h"
  44. #include "apr_pools.h"
  45. #include "apr_network_io.h"
  46. #include "llchainio.h"
  47. class LLHost;
  48. /** 
  49.  * @class LLSocket
  50.  * @brief Implementation of a wrapper around a socket.
  51.  *
  52.  * An instance of this class represents a single socket over it's
  53.  * entire life - from uninitialized, to connected, to a listening
  54.  * socket depending on it's purpose. This class simplifies our access
  55.  * into the socket interface by only providing stream/tcp and
  56.  * datagram/udp sockets - the only types we are interested in, since
  57.  * those are the only properly supported by all of our platforms.
  58.  */
  59. class LLSocket
  60. {
  61. public:
  62. /** 
  63.  * @brief Reference counted shared pointers to sockets.
  64.  */
  65. typedef boost::shared_ptr<LLSocket> ptr_t;
  66. /** 
  67.  * @brief Type of socket to create.
  68.  */
  69. enum EType
  70. {
  71. STREAM_TCP,
  72. DATAGRAM_UDP,
  73. };
  74. /** 
  75.  * @brief Anonymous enumeration to help identify ports
  76.  */
  77. enum
  78. {
  79. PORT_INVALID = (U16)-1,
  80. PORT_EPHEMERAL = 0,
  81. };
  82. /** 
  83.  * @brief Create a socket.
  84.  *
  85.  * This is the call you would use if you intend to create a listen
  86.  * socket. If you intend the socket to be known to external
  87.  * clients without prior port notification, do not use
  88.  * PORT_EPHEMERAL.
  89.  * @param pool The apr pool to use. A child pool will be created
  90.  * and associated with the socket.
  91.  * @param type The type of socket to create
  92.  * @param port The port for the socket
  93.  * @return A valid socket shared pointer if the call worked.
  94.  */
  95. static ptr_t create(
  96. apr_pool_t* pool,
  97. EType type,
  98. U16 port = PORT_EPHEMERAL);
  99. /** 
  100.  * @brief Create a LLSocket when you already have an apr socket.
  101.  *
  102.  * This method assumes an ephemeral port. This is typically used
  103.  * by calls which spawn a socket such as a call to
  104.  * <code>accept()</code> as in the server socket. This call should
  105.  * not fail if you have a valid apr socket.
  106.  * Because of the nature of how accept() works, you are expected
  107.  * to create a new pool for the socket, use that pool for the
  108.  * accept, and pass it in here where it will be bound with the
  109.  * socket and destroyed at the same time.
  110.  * @param socket The apr socket to use 
  111.  * @param pool The pool used to create the socket. *NOTE: The pool
  112.  * passed in will be DESTROYED.
  113.  * @return A valid socket shared pointer if the call worked.
  114.  */
  115. static ptr_t create(apr_socket_t* socket, apr_pool_t* pool);
  116. /** 
  117.  * @brief Perform a blocking connect to a host. Do not use in production.
  118.  *
  119.  * @param host The host to connect this socket to.
  120.  * @return Returns true if the connect was successful.
  121.  */
  122. bool blockingConnect(const LLHost& host);
  123. /** 
  124.  * @brief Get the type of socket
  125.  */
  126. //EType getType() const { return mType; }
  127. /** 
  128.  * @brief Get the port.
  129.  *
  130.  * This will return PORT_EPHEMERAL if bind was never called.
  131.  * @return Returns the port associated with this socket.
  132.  */
  133. U16 getPort() const { return mPort; }
  134. /** 
  135.  * @brief Get the apr socket implementation.
  136.  *
  137.  * @return Returns the raw apr socket.
  138.  */
  139. apr_socket_t* getSocket() const { return mSocket; }
  140. protected:
  141. /** 
  142.  * @brief Protected constructor since should only make sockets
  143.  * with one of the two <code>create()</code> calls.
  144.  */
  145. LLSocket(apr_socket_t* socket, apr_pool_t* pool);
  146. /** 
  147.  * @brief Set default socket options.
  148.  */
  149. void setOptions();
  150. public:
  151. /** 
  152.  * @brief Do not call this directly.
  153.  */
  154. ~LLSocket();
  155. protected:
  156. // The apr socket.
  157. apr_socket_t* mSocket;
  158. // our memory pool
  159. apr_pool_t* mPool;
  160. // The port if we know it.
  161. U16 mPort;
  162. //EType mType;
  163. };
  164. /** 
  165.  * @class LLIOSocketReader
  166.  * @brief An LLIOPipe implementation which reads from a socket.
  167.  * @see LLIOPipe
  168.  *
  169.  * An instance of a socket reader wraps around an LLSocket and
  170.  * performs non-blocking reads and passes it to the next pipe in the
  171.  * chain.
  172.  */
  173. class LLIOSocketReader : public LLIOPipe
  174. {
  175. public:
  176. LLIOSocketReader(LLSocket::ptr_t socket);
  177. ~LLIOSocketReader();
  178. protected:
  179. /* @name LLIOPipe virtual implementations
  180.  */
  181. //@{
  182. /** 
  183.  * @brief Process the data coming in the socket.
  184.  *
  185.  * Since the socket and next pipe must exist for process to make
  186.  * any sense, this method will return STATUS_PRECONDITION_NOT_MET
  187.  * unless if they are not known.
  188.  * If a STATUS_STOP returned by the next link in the chain, this
  189.  * reader will turn of the socket polling.
  190.  * @param buffer Pointer to a buffer which needs processing. Probably NULL.
  191.  * @param bytes Number of bytes to in buffer to process. Probably 0.
  192.  * @param eos True if this function is the last. Almost always false.
  193.  * @param read Number of bytes actually processed.
  194.  * @param pump The pump which is calling process. May be NULL.
  195.  * @param context A data structure to pass structured data
  196.  * @return STATUS_OK unless the preconditions are not met.
  197.  */
  198. virtual EStatus process_impl(
  199. const LLChannelDescriptors& channels,
  200. buffer_ptr_t& buffer,
  201. bool& eos,
  202. LLSD& context,
  203. LLPumpIO* pump);
  204. //@}
  205. protected:
  206. LLSocket::ptr_t mSource;
  207. std::vector<U8> mBuffer;
  208. bool mInitialized;
  209. };
  210. /** 
  211.  * @class LLIOSocketWriter
  212.  * @brief An LLIOPipe implementation which writes to a socket
  213.  * @see LLIOPipe
  214.  *
  215.  * An instance of a socket writer wraps around an LLSocket and
  216.  * performs non-blocking writes of the data passed in.
  217.  */
  218. class LLIOSocketWriter : public LLIOPipe
  219. {
  220. public:
  221. LLIOSocketWriter(LLSocket::ptr_t socket);
  222. ~LLIOSocketWriter();
  223. protected:
  224. /* @name LLIOPipe virtual implementations
  225.  */
  226. //@{
  227. /** 
  228.  * @brief Write the data in buffer to the socket.
  229.  *
  230.  * Since the socket pipe must exist for process to make any sense,
  231.  * this method will return STATUS_PRECONDITION_NOT_MET if it is
  232.  * not known.
  233.  * @param buffer Pointer to a buffer which needs processing.
  234.  * @param bytes Number of bytes to in buffer to process.
  235.  * @param eos True if this function is the last.
  236.  * @param read Number of bytes actually processed.
  237.  * @param pump The pump which is calling process. May be NULL.
  238.  * @param context A data structure to pass structured data
  239.  * @return A return code for the write.
  240.  */
  241. virtual EStatus process_impl(
  242. const LLChannelDescriptors& channels,
  243. buffer_ptr_t& buffer,
  244. bool& eos,
  245. LLSD& context,
  246. LLPumpIO* pump);
  247. //@}
  248. protected:
  249. LLSocket::ptr_t mDestination;
  250. U8* mLastWritten;
  251. bool mInitialized;
  252. };
  253. /** 
  254.  * @class LLIOServerSocket
  255.  * @brief An IOPipe implementation which listens and spawns connected
  256.  * sockets.
  257.  * @see LLIOPipe, LLChainIOFactory
  258.  *
  259.  * Each server socket instance coordinates with a pump to ensure it
  260.  * only processes waiting connections. It uses the provided socket,
  261.  * and assumes it is correctly initialized. When the connection is
  262.  * established, the server will call the chain factory to build a
  263.  * chain, and attach a socket reader and the front and a socket writer
  264.  * at the end. It is up to the chain factory to create something which
  265.  * correctly handles the established connection using the reader as a
  266.  * source, and the writer as the final sink.
  267.  * The newly added chain timeout is in DEFAULT_CHAIN_EXPIRY_SECS unless
  268.  * adjusted with a call to setResponseTimeout().
  269.  */
  270. class LLIOServerSocket : public LLIOPipe
  271. {
  272. public:
  273. typedef LLSocket::ptr_t socket_t;
  274. typedef boost::shared_ptr<LLChainIOFactory> factory_t;
  275. LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor);
  276. virtual ~LLIOServerSocket();
  277. /** 
  278.  * @brief Set the timeout for the generated chains.
  279.  *
  280.  * This value is passed directly to the LLPumpIO::addChain()
  281.  * method. The default on construction is set to
  282.  * DEFAULT_CHAIN_EXPIRY_SECS which is a reasonable value for most
  283.  * applications based on this library. Avoid passing in
  284.  * NEVER_CHAIN_EXPIRY_SECS unless you have another method of
  285.  * harvesting chains.
  286.  * @param timeout_secs The seconds before timeout for the response chain. 
  287.  */
  288. void setResponseTimeout(F32 timeout_secs);
  289. /* @name LLIOPipe virtual implementations
  290.  */
  291. //@{
  292. protected:
  293. /** 
  294.  * @brief Process the data in buffer
  295.  */
  296. virtual EStatus process_impl(
  297. const LLChannelDescriptors& channels,
  298. buffer_ptr_t& buffer,
  299. bool& eos,
  300. LLSD& context,
  301. LLPumpIO* pump);
  302. //@}
  303. protected:
  304. apr_pool_t* mPool;
  305. socket_t mListenSocket;
  306. factory_t mReactor;
  307. bool mInitialized;
  308. F32 mResponseTimeout;
  309. };
  310. #if 0
  311. /** 
  312.  * @class LLIODataSocket
  313.  * @brief BRIEF_DESC
  314.  *
  315.  * THOROUGH_DESCRIPTION
  316.  */
  317. class LLIODataSocket : public LLIOSocket
  318. {
  319. public:
  320. /**
  321.  * @brief Construct a datagram socket.
  322.  *
  323.  * If you pass in LLIOSocket::PORT_EPHEMERAL as the suggested
  324.  * port, The socket will not be in a 'listen' mode, but can still
  325.  * read data sent back to it's port. When suggested_port is not
  326.  * ephemeral or invalid and bind fails, the port discovery
  327.  * algorithm will search through a limited set of ports to
  328.  * try to find an open port. If that process fails, getPort() will
  329.  * return LLIOSocket::PORT_INVALID
  330.  * @param suggested_port The port you would like to bind. Use
  331.  * LLIOSocket::PORT_EPHEMERAL for an unspecified port.
  332.  * @param start_discovery_port The start range for
  333.  * @param pool The pool to use for allocation.
  334.  */
  335. LLIODataSocket(
  336. U16 suggested_port,
  337. U16 start_discovery_port,
  338. apr_pool_t* pool);
  339. virtual ~LLIODataSocket();
  340. protected:
  341. private:
  342. apr_socket_t* mSocket;
  343. };
  344. #endif
  345. #endif // LL_LLIOSOCKET_H