src/Network/TCP.hh
author terom
Tue, 16 Dec 2008 23:21:26 +0000
changeset 380 d193dd1d8a7e
parent 378 5589abf5e61b
child 381 9b35bc329d23
permissions -rw-r--r--
new NetworkReactor, fix everything to actually work
#ifndef NETWORK_TCP_HH
#define NETWORK_TCP_HH

#include <ClanLib/core.h>

#include "Socket.hh"
#include "Address.hh"
#include "Packet.hh"
#include "Buffer.hh"

// @{
/**
 * Initial input/output buffer size given to NetworkTCPTransport::in/out constructor
 *
 * @see NetworkBufferBase
 */
const size_t NETWORK_TCP_INITIAL_IN_BUF = 4096;
const size_t NETWORK_TCP_INITIAL_OUT_BUF = 0;
// @}

/**
 * A connected TCP socket, so either a client or a server-accept socket
 */
class NetworkTCPTransport {
    protected:
        /**
         * The SOCK_STREAM socket
         */
        NetworkSocket *socket;
        
        /**
         * Our input buffer associated with socket
         */
        NetworkBufferInput in;

        /**
         * Our output buffer associated with socket
         */
        NetworkBufferOutput out;
    
        CL_SlotContainer slots; 
    
    public:
        /**
         * Construct this using the given socket
         */
        NetworkTCPTransport (NetworkSocket *socket);
        
        /**
         * Deletes the socket
         */
        ~NetworkTCPTransport (void);

    private:
        /**
         * Triggered when the socket is read for recv
         */
        void on_read (void);

        /**
         * Triggered when the socket is read for send
         */
        void on_write (void);
        
        /**
         * The packet-read signal
         */
        CL_Signal_v1<NetworkPacketInput&> _sig_packet;

        /**
         * The disconnected-signal
         */
        CL_Signal_v0 _sig_disconnect;

    public:
        /**
         * Get this TCP socket's local address
         */
        NetworkAddress get_local_address (void) { return socket->get_local_address(); }

        /**
         * Get this TCP socket's remote address
         */
        NetworkAddress get_remote_address (void) { return socket->get_remote_address(); }
        
        /**
         * Write the given packet to this socket output, buffering the data if need be
         *
         * @param packet the packet to send
         */
        void write_packet (const NetworkPacketBuffer &packet);

        /**
         * Handle disconnect, disable socket
         */
        void handle_disconnect (void);
        
        /**
         * A full packet has been received from the remote end
         */
        CL_Signal_v1<NetworkPacketInput&>& sig_packet (void) { return _sig_packet; }

        /**
         * The connection has been lost (no specific error code given)
         */
        CL_Signal_v0& sig_disconnect (void) { return _sig_disconnect; }
};

/**
 * A TCP server, listening on the given address, creating NetworkTCPTransports for clients that connect
 */
class NetworkTCPServer {
    private:
        /**
         * The listen() socket
         */
        NetworkSocket socket;

        CL_SlotContainer slots; 

    public:
        /**
         * Listen on the specific address.
         */
        NetworkTCPServer (const NetworkAddress &listen_addr);

    private:
        /**
         * The socket is read for read()
         */
        void on_accept (void);
        
        /**
         * The on_accept signal
         */
        CL_Signal_v1<NetworkTCPTransport *> _sig_client;

    protected:
        /**
         * Called by on_accept to build the NetworkTCPTransport, can be used to override what class gets used.
         *
         * By default, this just constructs a new NetworkTCPTransport and returns it
         *
         * @param socket the socket returned by accept()
         */
        virtual NetworkTCPTransport* buildTransport (NetworkSocket *socket);

    public:
        /**
         * A new client has connected, and a NetworkTCPTransport has been connected for it
         */
        CL_Signal_v1<NetworkTCPTransport *>& sig_client (void) { return _sig_client; }
};

/**
 * A TCP Client that connects to the given address
 */ 
class NetworkTCPClient : public NetworkTCPTransport {
    public:
        /**
         * Create a NetworkTCPTransport, and then connect our socket to the given address.
         *
         * @param connect_addr the address to connect to
         */
        NetworkTCPClient (const NetworkAddress &connect_addr);
};

#endif /* NETWORK_TCP_HH */