// Copyright (c) 1999-2000 David Muse
// See the COPYING file for more information.

#ifndef SERVERSOCKET_H
#define SERVERSOCKET_H

#include <rudiments/genericsocket.h>

// The serversocket class allows you to write programs that can talk to other
// programs over TCP connections.
//
// The class supports TCP connections over Inet and Unix domain sockets.
// Inet sockets allow clients and servers on different machines to talk over a
// network.  Unix sockets allow clients and servers on the same machine to 
// talk.  Inet sockets can be used by clients and servers on the same machine
// but Unix sockets generally perform better.
//
// The serversocket class provides methods for setting up sockets and accepting
// client connections.  Its parent class: genericsocket, provides methods for 
// reading and writing data and error management.
//
// If you need to listen on more than 1 socket at a time, you should use the 
// serversocketpool class.

class serversocket : public genericsocket {
	public:
			serversocket();

		// Simple Socket Initialization Interface:
		//
		// The following 3 methods provide a simplified interface to
		// socket initialization.
		//
		// If you need to set socket options or do anything special
		// between the discrete steps of socket initialization, you
		// should use a combination of the methods following these 2.
		int	listenOnInetPort(unsigned short int port, int backlog);
				// Listen on inet port: "port" and allow 
				// "backlog" connections to pile up before 
				// refusing them.
				// Entering a value of 0 for the "port" causes
				// the server to listen on an arbitrary port.
				// The getPort() method can be used later to 
				// discover this port.
				//
				// Returns 1 on success and 0 on failure.
		int	listenOnUnixPort(char *port, mode_t mode, int backlog);
				// Listen on unix port: "port" and allow 
				// "backlog" connections to pile up before 
				// refusing them.  Set the permissions on
				// "port" to "permissions".
				//
				// Returns 1 on success and 0 on failure.


		// Complex Socket Initialization Interface:
		//
		// The following 7 methods provide discrete control over socket
		// initialization.
		//
		// If you need to set socket options or do anything special
		// between the discrete steps of socket initialization, you
		// should use a combination of these methods.
		int	initInetPort(unsigned short int port);
			// Associates the socket with inet port "port".
			//
			// Returns 1 on success and 0 on failure.
		int	initUnixPort(char *port, mode_t mode);
			// Associates the socket with unix port "port".
			//
			// Returns 1 on success and 0 on failure.

		int	lingerOnClose(int timeout);
			// Instructs the connection to the client to stay open
			// for "timeout" seconds even after closeSocket()
			// is called if the client hasn't received all of the
			// data yet.
			//
			// Returns 1 on success and 0 on failure.
		int	reuseAddresses();
			// Allows sockets in the TIME_WAIT state to be reused
			//
			// Returns 1 on success and 0 on failure.

		int		bindSocket();
				// Associates the socket with an address.
				//
				// Returns 1 on success and 0 on failure.
		int		listenForClientConnection(int backlog);
				// Waits until a client connects then places
				// that connection in queue.  Up to "backlog"
				// connections may be queued before future
				// conenctions are refused.
				//
				// Returns 1 on success and 0 on failure.
		genericsocket	*acceptClientConnection();
				// Removes the client connection from the queue
				// and associates a new socket with that
				// connection.  Communication with the client
				// may be done over this new socket.  
				//
				// Returns a genericsocket on success and NULL
				// on failure.

		int		stopListening();
				// Disconnects the server process from the 
				// port it's listening on.

		unsigned short int	getPort();
					// Returns the inet port number that
					// the socket is listening on.  If the
					// port has not been set or if the
					// socket is a unix socket, 0 is 
					// returned instead.

		static int	getClientAddress(genericsocket *sock, 
							char *buffer);
				// Writes the address of the client at
				// the other end of "sock" to "buffer".

	protected:
		#include <rudiments/private/serversocket.h>

};

#endif
