LibGTcpSocket

1. OVERVIEW:
================================================================================
LibGTcpSocket is a networking wrapper written in pure C against the Glib/GObject
object framework.

Requires:
	GLib 2.0 with thread support
	GConf 2.0
Optional:
	OpenSSL 0.9.6 (for SSL support)

The intention here is to provide a useful and easy-to-develop-against sockets
wrapper for GNOME2 & GTK+ 2.0 programs which require TCP/IP connection
capabilities. It can be used by programs which do not use GNOME or GTK+ anyways,
however. It is NOT recommended or intended for high-load server situations,
just user applications which need TCP/IP networking. Proxies are supported
completely transparently, 


2. OBJECTS:
================================================================================
LibGTcpSocket provides the following objects:

	GTcpConnection
	GTcpServer

These objects are subclasses of Glib's GObject.

2.1 GTcpConnection:
---------------
A GTcpConnection object is a wrapper around the standard outgoing connections
code, complete with SSL support.

2.2 GTcpServer:
---------------
A GTcpServer object is a wrapper around the standard incoming connections code.
It creates GTcpConnection objects as needed to handle incoming connections
individually. You should connect the "connect" signal of the GTcpServer to a
function which correctly handles each individual GTcpConnection.


3. Simple Examples:
================================================================================

3.1 GTcpConnection
--------------
Example connecting to port 80 of localhost:

	/* A GFunc to be added with g_idle_add, that is, the GMainLoop should've
	   already been started by the time this function is called. */
	gboolean
	do_tcp_connection (gpointer data)
	{
		GObject *connection;

		connection = gtcp_connection_new ("127.0.0.1", 80);
		g_signal_connect (connection, "lookup-done", lookup_callback, NULL);
		g_signal_connect (connection, "connect-done", connect_callback, NULL);
		g_signal_connect (connection, "recv", recv_callback, NULL);
		g_signal_connect (connection, "send", send_callback, NULL);
		gtcp_connection_open (GTCP_CONNECTION (connection));

		return FALSE;
	}

	void
	lookup_callback (GTcpConnection *connection, GTcpLookupStatus status,
	                 gpointer user_data)
	{
		/* If the status is != 0, then something failed. See the
		   documentation or the header file for more information. */
		if (status)
		{
			g_message ("Lookup Error: %s",
			           gtcp_error_get_lookup_status_message (status,
			                                                 "127.0.0.1"));
		}
		else
		{
			g_message ("Lookup suceeded.");
		}
	}

	void
	connect_callback (GTcpClient *client, GTcpConnectionStatus status,
	                  gpointer user_data)
	{
		/* If none of the IP addresses returned by DNS succeded */
		if (status < GTCP_CONNECTION_CONNECTED)
		{
			g_message ("Connection Error: %s",
			           gtcp_error_get_connection_status_message (status,
			                                                     "127.0.0.1"));
		}
		else
		{
			g_message ("Connection suceeded.");
		}
	}

	void
	recv_callback (GTcpClient *client, gconstpointer data, gsize length,
	               gpointer user_data)
	{
		g_message ("Recieved Data: '%s'", (gchar *) data);
	}

	void
	send_callback (GTcpClient *client, gconstpointer data, gsize length,
	               gpointer user_data)
	{
		g_message ("Sent Data: '%s'", (gchar *) data);
	}


3.2 GTcpServer & GTcpConnection
-------------------------------------
Example recieving a maximum of 10 connections to port 80:

	gboolean
	do_tcp_server (gpointer data)
	{
		GObject *server;
		GTcpServerOpenStatus status;

		server = gtcp_server_new (80, FALSE, NULL);
		/* Allow a maximum of 10 connections */
		gtcp_server_set_max_connections (GTCP_SERVER (server), 10);
		/* Close all GTcpConnections opened by this server when the
		   server is finalized (with g_object_unref) */
		gtcp_server_set_kill_style (GTCP_SERVER (server),
									GTCP_SERVER_FINALIZE_ON_FINALIZE);
		g_signal_connect (server, "connect", connect_callback, NULL);
		status = gtcp_server_open (G_TCP_SERVER (server);

		if (status)
		{
			g_message ("Server Open Error: %s", 
			           gtcp_error_get_server_open_status_message (status, 80));
		}

		return FALSE;
	}

	void
	connect_callback (GTcpServer *server, GTcpConnection *conn,
	                  gpointer user_data)
	{
		g_signal_connect (conn, "recv", recv_callback, NULL);
		g_signal_connect (conn, "send", send_callback, NULL);
	}
	
	void
	recv_callback (GTcpConnection *conn, gconstpointer data, gsize length,
	               gpointer user_data)
	{
		gchar *addr;
		guint port;

		g_object_get (conn,
		              "ip-address", &addr,
		              "remote-port", &port,
		              NULL);

		g_message ("Recieved data from %s:%d: '%s'\n", addr, port, (gchar *) data);
	}
	
	void
	send_callback (GTcpConnection *conn, gconstpointer data, gsize length,
	               gpointer user_data)
	{
		gchar *addr;
		guint port;

		g_object_get (conn,
		              "ip-address", &addr,
		              "remote-port", &port,
		              NULL);

		g_message ("Sent data to %s:%d: '%s'\n", addr, port, (gchar *) data);
	}
