00001 /* 00002 * netlib.h 00003 * 00004 * Copyright (C) 2007,2009,2010 Thomas A. Vaughan 00005 * All rights reserved. 00006 * 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions are met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * * Neither the name of the <organization> nor the 00016 * names of its contributors may be used to endorse or promote products 00017 * derived from this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY 00020 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00022 * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY 00023 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00026 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 * 00030 * 00031 * Networking library. This is a layer on top of BSD sockets that handles 00032 * some threading etc. Somewhat tailored to my specific applications. 00033 */ 00034 00035 #ifndef WAVEPACKET_NETLIB_H__ 00036 #define WAVEPACKET_NETLIB_H__ 00037 00038 00039 // includes -------------------------------------------------------------------- 00040 #include "message-buffer.h" 00041 #include "wavesock.h" 00042 00043 00044 namespace netlib { 00045 00046 00047 // networking typedefs --------------------------------------------------------- 00048 00049 //////////////////////////////////////////////////////////////////////////////// 00050 /// 00051 /// \ingroup networking 00052 /// \defgroup netlib Networking API 00053 /// 00054 /// This is a very basic networking API layer. You can create connections 00055 /// (using the various constructors) and get back a connection ID. Then 00056 /// you can read/write to the connection based on the ID. 00057 /// 00058 /// You can write to the connection any time using the connection ID. 00059 /// 00060 /// <b>The getNextMessage() API is the core message pump.</b> 00061 /// The application should repeatedly call this so that messages get sent 00062 /// in and out. 00063 /// 00064 /// \b WARNING: this library is NOT threadsafe! You should handle any 00065 /// synchronization issues at a higher layer. 00066 /// 00067 //////////////////////////////////////////////////////////////////////////////// 00068 /*@{*/ 00069 00070 /// connection ID type. Will never be null for a valid connection. 00071 typedef dword_t conn_id_t; 00072 00073 00074 /// the type of connection 00075 enum eConnectionType { 00076 eType_TCP = 0x0001, ///< standard tcp/ip connection 00077 eType_SecureTCP = 0x0002, ///< ssl connection 00078 00079 eType_UDPLocal = 0x0010, ///< can send/receive UDP datagrams 00080 eType_UDPRemote = 0x0020, ///< our record of remote UDP socket 00081 eType_UDPBroadcast = 0x0040, ///< can broadcast UDP datagrams 00082 00083 eType_TCPListener = 0x0100, ///< local tcp listening socket 00084 00085 // must be last! 00086 eType_Invalid = 0 00087 }; 00088 00089 00090 00091 struct connection_info_t { 00092 // constructor, manipulator 00093 connection_info_t(void) throw() { this->clear(); } 00094 void clear(void) throw() { 00095 type = eType_Invalid; 00096 address.clear(); 00097 port = 0; 00098 } 00099 bool is_valid(void) const throw() { 00100 return (eType_Invalid != type); 00101 } 00102 void dump(IN const char * title) const throw(); 00103 00104 // data fields 00105 eConnectionType type; 00106 address_t address; 00107 int port; 00108 }; 00109 00110 00111 00112 /// An envelope describes from where and how a remote message arrived 00113 struct envelope_t { 00114 // constructor, manipulators 00115 envelope_t(void) throw() { this->clear(); } 00116 void clear(void) throw() { 00117 fromConnId = 0; 00118 type = eType_Invalid; 00119 address.clear(); 00120 } 00121 bool is_empty(void) const throw() { 00122 return (eType_Invalid == type); 00123 } 00124 bool isValid(void) const throw() { 00125 if (eType_Invalid == type) 00126 return false; 00127 if (fromConnId) 00128 return true; // assume so... 00129 return address.isValid(); 00130 } 00131 00132 // data fields 00133 conn_id_t fromConnId; /// source connection ID 00134 eConnectionType type; 00135 address_t address; 00136 }; 00137 00138 00139 00140 00141 //////////////////////////////////////////////////////////////////////////////// 00142 // 00143 // public API 00144 // 00145 //////////////////////////////////////////////////////////////////////////////// 00146 /// \ingroup netlib 00147 /*@{*/ 00148 00149 00150 /// return the hostname (or IP in string form!) 00151 std::string getServerFromIP(IN const ip_addr_t& ip); 00152 00153 00154 /// create a listener (if clients connect, you'll see their messages show up) 00155 conn_id_t createTcpListener(IN const address_t& address, 00156 IN int maxBacklog); 00157 00158 /// create a connection to a remote peer (connection ID is returned) 00159 conn_id_t createTcpConnection(IN const address_t& address); 00160 00161 00162 /// create a local UDP connection for sending/receiving datagrams. 00163 /// This connection will receive datagrams sent to this local port from any 00164 /// remote location (including broadcast packets). 00165 /// You have to specify the full local address. This is important for 00166 /// machines with multiple interfaces, and even for a machine with a 00167 /// single interface, you need to specify the physical interface vs. 00168 /// a local host loopback (127.0.0.1). 00169 /// To send UDP datagrams from this connection, create a remote UDP 00170 /// connection using createUdpRemote() and use this connection as the 00171 /// localUdp connection. 00172 /// To broadcast UDP datagrams, you won't use this connection at all. Instead, 00173 /// create a broadcast UDP datagram connection using createUdpBroadcast(). 00174 conn_id_t createUdpLocal(IN const address_t& localUdp); 00175 00176 /// create a logical connection to represent a remote UDP sender/receiver 00177 /// - caller must specify the local UDP connection that will communicate 00178 /// this is used for sending to remote UDP listeners 00179 conn_id_t createUdpRemote(IN conn_id_t localUdp, 00180 IN const address_t& address); 00181 00182 /// create a local UDP sending point for datagram broadcasts to a specific port. 00183 /// Caller must specify the broadcast address, such as 192.168.0.255 00184 conn_id_t createUdpBroadcast(IN const address_t& broadcastAddress); 00185 00186 00187 /// asynchronously send data to a particular connection 00188 /// - conn_id specifies the (remote) receiver 00189 /// - queued messages are actually sent via getNextMessage() calls 00190 bool enqueueMessage(IN conn_id_t connId, 00191 IN smart_ptr<MessageBuffer>& message); 00192 00193 00194 /// get next message from all open connections (empty if no messages waiting) 00195 /// - this is the main message pump so applications should keep calling it 00196 bool getNextMessage(IN long wait_microseconds, 00197 OUT netlib::envelope_t& envelope, 00198 OUT smart_ptr<MessageBuffer>& buffer); 00199 00200 00201 /// is this a valid connection? 00202 bool isValidConnection(IN conn_id_t conn_id); 00203 00204 00205 /// given a connection, retrieve information about it 00206 bool getConnectionInfo(IN conn_id_t conn_id, 00207 OUT connection_info_t& info); 00208 00209 /// terminate a particular connection 00210 void closeConnection(IN conn_id_t conn_id); 00211 00212 /// for debugging 00213 void dumpMessage(IO std::ostream& stream, 00214 IN const char * title, 00215 IN const envelope_t& envelope, 00216 IN const MessageBuffer * buffer); 00217 00218 /// info only 00219 void dumpStats(void); 00220 00221 00222 }; // netlib namespace 00223 00224 00225 00226 #endif // WAVEPACKET_NETLIB_H__ 00227