[gnio] Update and build test/server.c
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnio] Update and build test/server.c
- Date: Mon, 4 May 2009 15:41:11 -0400 (EDT)
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]