Shadowrun: Awakened 29 September 2011 - Build 871
TCPConnection.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 #ifndef CAT_THREAD_POOL_SOCKETS_HPP
00030 #define CAT_THREAD_POOL_SOCKETS_HPP
00031 
00032 /*
00033     Windows version of thread pool sockets with IO Completion Ports
00034 
00035     Included from <cat/net/ThreadPoolSockets.hpp>
00036     Do not include directly
00037 */
00038 
00039 #include <MSWSock.h>
00040 #include <cat/port/WindowsInclude.hpp>
00041 
00042 namespace cat {
00043 
00044 /*
00045     class TCPConnection
00046 
00047     Object that represents a TCPServer's connection from a TCPClient
00048 
00049     Object is instantiated just before accepting a connection
00050 
00051     DisconnectClient()      : Disconnect the client
00052     PostToClient()          : Send a message to the client
00053     ValidServerConnection() : Returns true iff the connection is valid
00054 
00055     OnConnectFromClient()   : Return false to deny this connection
00056     OnReadFromClient()      : Return false to disconnect the client in response to a message
00057     OnWriteToClient()       : Informs the derived class that data has been sent
00058     OnDisconectFromClient() : Informs the derived class that the client has disconnected
00059 */
00060 class TCPConnection : public ThreadRefObject
00061 {
00062     friend class TCPServer;
00063     friend class ThreadPool;
00064 
00065 public:
00066     TCPConnection();
00067     virtual ~TCPConnection();
00068 
00069     bool ValidServerConnection();
00070 
00071     void DisconnectClient();
00072     bool PostToClient(void *buffer, u32 bytes);
00073 
00074 protected:
00075     virtual bool OnConnectFromClient(const NetAddr &remoteClientAddress) = 0; // false = disconnect
00076     virtual bool OnReadFromClient(u8 *data, u32 bytes) = 0; // false = disconnect
00077     virtual void OnWriteToClient(u32 bytes) = 0;
00078     virtual void OnDisconnectFromClient() = 0;
00079 
00080 private:
00081     Socket _socket;
00082     LPFN_DISCONNECTEX _lpfnDisconnectEx;
00083     TypedOverlapped *_recvOv;
00084     volatile u32 _disconnecting;
00085 
00086 private:
00087     bool AcceptConnection(Socket listenSocket, Socket acceptSocket,
00088                 LPFN_DISCONNECTEX lpfnDisconnectEx, const NetAddr &acceptAddress,
00089                 const NetAddr &remoteClientAddress);
00090 
00091     bool QueueWSARecv();
00092     void OnWSARecvComplete(int error, u32 bytes);
00093 
00094     bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes);
00095     void OnWSASendComplete(int error, u32 bytes);
00096 
00097     bool QueueDisconnectEx();
00098     void OnDisconnectExComplete(int error);
00099 };
00100 
00101 
00102 /*
00103     class TCPClient
00104 
00105     Object that represents a TCPClient bound to a single port
00106 
00107     ValidClient()      : Returns true iff the client socket is valid
00108 
00109     Connect()          : Connects to the given address
00110     DisconnectServer() : Disconnects from the server
00111     PostToServer()     : Send a message to the server (will fail if not connected)
00112 
00113     OnConnectToServer()      : Called when connection is accepted
00114     OnReadFromServer()       : Return false to disconnect the server in response to data
00115     OnWriteToServer()        : Informs the derived class that data has been sent
00116     OnDisconnectFromServer() : Informs the derived class that the server has disconnected
00117 */
00118 class TCPClient : public ThreadRefObject
00119 {
00120     friend class ThreadPool;
00121 
00122 public:
00123     TCPClient();
00124     virtual ~TCPClient();
00125 
00126     bool ValidClient();
00127 
00128     bool Connect(const NetAddr &remoteServerAddress);
00129     void DisconnectServer();
00130     bool PostToServer(void *buffer, u32 bytes);
00131 
00132 protected:
00133     virtual void OnConnectToServer() = 0;
00134     virtual bool OnReadFromServer(u8 *data, u32 bytes) = 0; // false = disconnect
00135     virtual void OnWriteToServer(u32 bytes) = 0;
00136     virtual void OnDisconnectFromServer() = 0;
00137 
00138 private:
00139     Socket _socket;
00140     TypedOverlapped *_recvOv;
00141     volatile u32 _disconnecting;
00142     bool _ipv6;
00143 
00144 private:
00145     bool QueueConnectEx(const NetAddr &remoteServerAddress);
00146     void OnConnectExComplete(int error);
00147 
00148     bool QueueWSARecv();
00149     void OnWSARecvComplete(int error, u32 bytes);
00150 
00151     bool QueueWSASend(TypedOverlapped *sendOv, u32 bytes);
00152     void OnWSASendComplete(int error, u32 bytes);
00153 
00154     bool QueueDisconnectEx();
00155     void OnDisconnectExComplete(int error);
00156 };
00157 
00158 
00159 /*
00160     class TCPClientQueued
00161 
00162     Base class for a TCP client that needs to queue up data for sending before
00163     a connection has been established.  e.g. Uplink for a proxy server.
00164 
00165     PostQueuedToServer() : Call in OnConnectToServer() to post the queued messages.
00166 */
00167 class TCPClientQueued : public TCPClient
00168 {
00169 private:
00170     volatile bool _queuing;
00171 
00172     Mutex _queueLock;
00173     void *_queueBuffer;
00174     u32 _queueBytes;
00175 
00176 protected:
00177     void PostQueuedToServer();
00178 
00179 public:
00180     TCPClientQueued();
00181     virtual ~TCPClientQueued();
00182 
00183     bool PostToServer(void *buffer, u32 bytes);
00184 };
00185 
00186 
00187 /*
00188     class UDPEndpoint
00189 
00190     Object that represents a UDP endpoint bound to a single port
00191 */
00192 class UDPEndpoint : public ThreadRefObject
00193 {
00194     friend class ThreadPool;
00195 
00196 public:
00197     UDPEndpoint();
00198     virtual ~UDPEndpoint();
00199 
00200     bool Valid();
00201     Port GetPort();
00202 
00203     // Is6() result is only valid AFTER Bind()
00204     CAT_INLINE bool Is6() { return _ipv6; }
00205 
00206     // For servers: Bind() with ignoreUnreachable = true ((default))
00207     // For clients: Bind() with ignoreUnreachable = false and call this
00208     //              after the first packet from the server is received.
00209     bool IgnoreUnreachable();
00210 
00211     void Close(); // Invalidates this object
00212     bool Bind(Port port = 0, bool ignoreUnreachable = true);
00213     bool QueueWSARecvFrom();
00214 
00215     // If Is6() == true, the address must be promoted to IPv6
00216     // before calling Post() with addr.PromoteTo6()
00217     bool Post(const NetAddr &addr, void *data, u32 bytes);
00218 
00219 protected:
00220     virtual void OnRead(ThreadPoolLocalStorage *tls, const NetAddr &addr, u8 *data, u32 bytes) = 0; // false = close
00221     virtual void OnWrite(u32 bytes) = 0;
00222     virtual void OnClose() = 0;
00223     virtual void OnUnreachable(const NetAddr &addr) {} // Only IP is valid
00224 
00225 private:
00226     Socket _socket;
00227     Port _port;
00228     volatile u32 _closing;
00229     bool _ipv6;
00230 
00231 private:
00232     bool QueueWSARecvFrom(RecvFromOverlapped *recvOv);
00233     void OnWSARecvFromComplete(ThreadPoolLocalStorage *tls, int error, RecvFromOverlapped *recvOv, u32 bytes);
00234 
00235     bool QueueWSASendTo(const NetAddr &addr, TypedOverlapped *sendOv, u32 bytes);
00236     void OnWSASendToComplete(int error, u32 bytes);
00237 };
00238 
00239 
00240 } // namespace cat
00241 
00242 #endif // CAT_THREAD_POOL_SOCKETS_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net