Listing 1: TCP class hierarchy interface


class IPaddress
{
  friend class SocketAddr;
  
  unsigned long address;        // Address: 4 bytes in the network
                                // byte order
  IPaddress(const unsigned int netaddr) : address(netaddr) {}

public:
  IPaddress(void)   { address = INADDR_ANY; }   // Wildcard address
  IPaddress(const char * name);        // Involves the name resolution
  unsigned long net_addr(void) const { return address; }
  operator const char * (void) const; // get a STATIC symbolic
                                      // representation of an IP 
                                      // address
};

class SocketAddr : sockaddr_in
{
  friend class StreamSocket;
  SocketAddr(void) {}
public:
  SocketAddr(const IPaddress host, const short port_no);
  operator sockaddr * (void) const      { return (sockaddr *)this; }
  operator const char * (void) const;   // Give a STATIC string
                                        // representation
};

                            // This can be either listening (passive)
                            // socket or connective (active) socket.
                            // That's why we don't have a public
                            // constructor here
class StreamSocket
{
public:
  enum Status { Good, Nodata, Eof, Failure };

protected:
  const int socket_handle;             // Socket handle = file handle
  Status status;

  StreamSocket(void);

public:
  StreamSocket(const int _socket_handle);    // wrap a class around
  ~StreamSocket(void);
  SocketAddr get_my_name(void) const;        // Name of this socket
  SocketAddr get_peer_name(void) const;      // Name of the socket this
                                             // socket is connected to
  void print(const char * title) const;      // Print the socket status

  void set_blocking_io(const BOOL onoff);
  void enable_sigio(const BOOL onoff);

                                // Write to the socket, return status
  Status write(const void * buffer, const unsigned int len);
                                // Read from the socket returning the
                                // status and size of the block read
  struct ReadResult { unsigned int len; Status status; };
  ReadResult read(void * buffer, const unsigned int len);
};

class Listen : public StreamSocket
{
public:
  Listen(const SocketAddr bind_address);
  StreamSocket * accept(const int backlog=1);
};

                         // This is a socket to initiate an active
                         // TCP open, that is, a connection. The
                         // constructor attempts to connect to another
                         // (hopefully listening) socket on
                         // probably another computer/port
class ConnectingSocket : public StreamSocket
{
public:
  ConnectingSocket(const SocketAddr target_address);
};
/* End of File */