[gnio] Update and build test/server.c



commit 297f244ccbc2091625f04801027449d3324a662f
Author: Alexander Larsson <alexl redhat com>
Date:   Mon May 4 21:37:48 2009 +0200

    Update and build test/server.c
    
    Add all sorts of useful stuff to test GSocket as a server.
---
 configure.ac     |    1 +
 test/Makefile.am |    5 +
 test/server.c    |  319 +++++++++++++++++++++++++++++++++++++-----------------
 3 files changed, 228 insertions(+), 97 deletions(-)

diff --git a/configure.ac b/configure.ac
index 63fd191..5400f3c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -127,5 +127,6 @@ AC_OUTPUT([
   gio/Makefile
   gio/gnio.pc
   examples/Makefile
+  test/Makefile
   Makefile
 ])
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..8ca1e3a
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,5 @@
+noinst_PROGRAMS = server
+
+AM_CFLAGS = $(gio_CFLAGS) -I$(top_srcdir) -Wall -Wmissing-prototypes -DGIO_COMPILATION
+server_LDADD = ../gio/libgnio.la $(gthread_LIBS)
+server_SOURCES = server.c
diff --git a/test/server.c b/test/server.c
index 0b2d8ef..bcc80d8 100644
--- a/test/server.c
+++ b/test/server.c
@@ -1,127 +1,252 @@
 #include <gio/gio.h>
-#include <gnio/gsocket.h>
-#include <gnio/ginetsocketaddress.h>
-#include <gnio/ginet4address.h>
+#include <gio/gsocket.h>
 #include <glib.h>
 #include <sys/socket.h>
 #include <errno.h>
 
 GMainLoop *loop;
 
-void accept_callback (GSocket *socket, GAsyncResult *result, gpointer data);
-
-/*
-gboolean
-accept_source (gpointer data)
+int port = 31882;
+gboolean verbose = FALSE;
+gboolean dont_reuse_address = FALSE;
+gboolean non_blocking = FALSE;
+gboolean use_udp = FALSE;
+
+static GOptionEntry cmd_entries[] = {
+  {"port", 'p', 0, G_OPTION_ARG_INT, &port,
+   "Local port to bind to", NULL},
+  {"udp", 'u', 0, G_OPTION_ARG_NONE, &use_udp,
+   "Use udp instead of tcp", NULL},
+  {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+   "Be verbose", NULL},
+  {"no-reuse", 0, 0, G_OPTION_ARG_NONE, &dont_reuse_address,
+   "Don't SOADDRREUSE", NULL},
+  {"non-blocking", 'n', 0, G_OPTION_ARG_NONE, &non_blocking,
+   "Enable non-blocking i/o", NULL},
+  {NULL}
+};
+
+static char *
+socket_address_to_string (GSocketAddress *address)
 {
-	GSocket *socket = G_SOCKET (data);
-
-	g_print ("in source\n");
-
-	g_socket_accept_async (socket, NULL, (GAsyncReadyCallback) accept_callback, NULL);
-
-	return FALSE;	
+  GInetAddress *inet_address;
+  char *str, *res;
+  int port;
+
+  inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address));
+  str = g_inet_address_to_string (inet_address);
+  port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address));
+  res = g_strdup_printf ("%s:%d", str, port);
+  g_free (str);
+  return res;
 }
 
-void
-accept_callback (GSocket *socket, GAsyncResult *result, gpointer data)
+int
+main (int argc,
+      char *argv[])
 {
-	GSocket *new_socket;
-	GSocketAddress *address;
-	GError *error = NULL;
-
-	g_print ("in callback\n");
-
-	new_socket = g_socket_accept_finish (socket, result, &error);
-
-	if (!new_socket)
-		g_error (error->message);
-
-	address = g_socket_get_remote_address (new_socket, &error);
-
-	if (!address)
-		g_error (error->message);
-
-	g_print ("got a new connection from %s:%d\n", g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))), g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)));
-
-	g_idle_add (accept_source, (gpointer) socket);
-}
-*/
-
-int main (int argc, char *argv[])
-{
-	GSocket *socket, *new_socket;
-	GSocketAddress *address;
-	GError *error = NULL;
-
-	g_thread_init (NULL);
-
-	g_type_init ();
-
-	loop = g_main_loop_new (NULL, FALSE);
-
-	socket = g_socket_new (G_SOCKET_DOMAIN_INET, G_SOCKET_TYPE_STREAM, NULL, NULL);
+  GSocket *socket, *new_socket, *recv_socket;
+  GSocketAddress *src_address;
+  GSocketAddress *address;
+  GSocketType socket_type;
+  GError *error = NULL;
+  GOptionContext *context;
+
+  g_thread_init (NULL);
+
+  g_type_init ();
+
+  context = g_option_context_new (" - Test GSocket server stuff");
+  g_option_context_add_main_entries (context, cmd_entries, NULL);
+  if (!g_option_context_parse (context, &argc, &argv, &error))
+    {
+      g_printerr ("%s: %s\n", argv[0], error->message);
+      return 1;
+    }
+
+  loop = g_main_loop_new (NULL, FALSE);
+
+  if (use_udp)
+    socket_type = G_SOCKET_TYPE_DATAGRAM;
+  else
+    socket_type = G_SOCKET_TYPE_STREAM;
+
+  socket = g_socket_new (G_SOCKET_FAMILY_IPV4, socket_type, NULL);
+
+  if (g_socket_has_error (socket, &error))
+    {
+      g_printerr ("%s: %s\n", argv[0], error->message);
+      return 1;
+    }
+
+  if (!dont_reuse_address)
+    g_socket_set_reuse_address (socket, TRUE);
+
+  if (non_blocking)
+    g_socket_set_blocking (socket, FALSE);
+
+  src_address = g_inet_socket_address_new (g_inet_address_new_any (G_SOCKET_FAMILY_IPV4), port);
+  if (!g_socket_bind (socket, src_address, &error))
+    {
+      g_printerr ("Can't bind socket: %s\n", error->message);
+      return 1;
+    }
+
+  if (!use_udp)
+    {
+      if (!g_socket_listen (socket, &error))
+	{
+	  g_printerr ("Can't listen on socket: %s\n", error->message);
+	  return 1;
+	}
 
-	g_socket_set_reuse_address (socket, TRUE);
+      g_print ("listening on port %d...\n", port);
 
-	if (!g_socket_bind (socket, G_SOCKET_ADDRESS (g_inet_socket_address_new (G_INET_ADDRESS (g_inet4_address_from_string ("127.0.0.1")), 31882)), &error)) {
-		g_error (error->message);
-		return 0;
+      if (non_blocking &&
+	  !g_socket_condition_wait (socket, G_IO_IN, NULL, &error))
+	{
+	  g_printerr ("accepting condition wait error: %s\n",
+		      error->message);
+	  return 1;
 	}
-
-	if (!g_socket_listen (socket, &error)) {
-		g_error (error->message);
-		return 0;
+      new_socket = g_socket_accept (socket, &error);
+      if (!new_socket)
+	{
+	  g_printerr ("Error accepting socket: %s\n",
+		      error->message);
+	  return 1;
 	}
 
-	g_print ("listening on port 31882...\n");
-
-	new_socket = g_socket_accept (socket, &error);
+      if (non_blocking)
+	g_socket_set_blocking (new_socket, FALSE);
 
-	if (!new_socket) {
-		g_error (error->message);
-		return 0;
+      address = g_socket_get_remote_address (new_socket, &error);
+      if (!address)
+	{
+	  g_printerr ("Error getting remote address: %s\n",
+		      error->message);
+	  return 1;
 	}
 
-	address = g_socket_get_remote_address (new_socket, &error);
-
-	if (!address) {
-		g_error (error->message);
-		return 0;
+      g_print ("got a new connection from %s (blocking: %d)\n",
+	       socket_address_to_string (address),
+	       g_socket_get_blocking (new_socket));
+
+      recv_socket = new_socket;
+    }
+  else
+    {
+      recv_socket = socket;
+      new_socket = NULL;
+    }
+
+
+  while (TRUE)
+    {
+      gchar buffer[4096] = { };
+      gssize size;
+      gsize to_send;
+      GInputVector v;
+      GOutputVector ov;
+
+      v.buffer = buffer;
+      ov.buffer = buffer;
+
+      if (non_blocking &&
+	  !g_socket_condition_wait (recv_socket, G_IO_IN, NULL, &error))
+	{
+	  g_printerr ("receive condition wait error: %s\n",
+		      error->message);
+	  return 1;
 	}
 
-	g_print ("got a new connection from %s:%d\n", g_inet_address_to_string (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (address))), g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (address)));
-
-	while (TRUE) {
-		gchar buffer[128] = { };
-		gssize size;
-
-		if ((size = g_socket_receive (new_socket, buffer, 128, &error)) < 0) {
-			g_error (error->message);
-			return 0;
-		}
-
-		if (size == 0)
-			break;
+      if (use_udp)
+	{
+	  v.size = sizeof buffer;
+	  size = g_socket_receive_message (recv_socket,
+					   &address,
+					   &v, 1,
+					   NULL, 0, NULL, &error);
+	}
+      else
+	size = g_socket_receive (recv_socket, buffer, sizeof buffer, &error);
+
+      if (size < 0)
+	{
+	  g_printerr ("Error recieving from socket: %s\n",
+		      error->message);
+	  return 1;
+	}
 
-		g_print ("received %" G_GSSIZE_FORMAT " bytes of data: %s\n", size, buffer);
+      if (size == 0)
+	break;
+
+      g_print ("received %" G_GSSIZE_FORMAT " bytes of data", size);
+      if (use_udp)
+	g_print (" from %s", socket_address_to_string (address));
+      g_print ("\n");
+
+      if (verbose)
+	g_print ("-------------------------\n"
+		 "%.*s\n"
+		 "-------------------------\n",
+		 (int)size, buffer);
+
+      to_send = size;
+
+      while (to_send > 0)
+	{
+	  if (use_udp)
+	    {
+	      ov.size = to_send;
+	      size = g_socket_send_message (recv_socket,
+					    address,
+					    &ov, 1,
+					    NULL, 0,
+					    0, &error);
+	    }
+	  else
+	    size = g_socket_send (recv_socket, buffer, to_send, &error);
+
+	  if (size < 0)
+	    {
+	      g_printerr ("Error sending to socket: %s\n",
+			  error->message);
+	      return 1;
+	    }
+
+	  if (size == 0)
+	    {
+	      g_printerr ("Unexpected short write\n");
+	      return 1;
+	    }
+
+	  to_send -= size;
+	}
+    }
 
-		if ((size = g_socket_send (new_socket, buffer, size, &error)) < 0) {
-			g_error (error->message);
-			return 0;
-		}
+  g_print ("connection closed\n");
 
-		if (size == 0)
-			break;
+  if (new_socket)
+    {
+      if (!g_socket_close (new_socket, &error))
+	{
+	  g_printerr ("Error closing connection socket: %s\n",
+		      error->message);
+	  return 1;
 	}
 
-	g_print ("connection closed\n");
-
-	g_object_unref (G_OBJECT (new_socket));
+      g_object_unref (G_OBJECT (new_socket));
+    }
 
-	g_socket_close (socket);
+  if (!g_socket_close (socket, &error))
+    {
+      g_printerr ("Error closing master socket: %s\n",
+		  error->message);
+      return 1;
+    }
 
-	g_object_unref (G_OBJECT (socket));
+  g_object_unref (G_OBJECT (socket));
 
-	return 0;
+  return 0;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]