Re: [gnet] Gnet-2.0.7 and win32



Title: Re: [gnet] Gnet-2.0.7 and win32

Hello again.

The netcat for Linux I used is the standard from Debian/Sarge (1.10-27)
and the windows port is the one from here:

 http://www.atstake.com/research/tools/

But I only use netcat to test if a simple client can read and write
over a TCP/IP connection. When netcat is started like this:

 nc -l -p 1234

It starts a server on port 1234 and when a line is entered then the line is
sent to the connected client (if there is a client connected).
Lines that are sent from the client to netcat are printed to stdout.

When run on Linux, lines entered in the netcat xterm will show up in the echoclient xterm
and lines entered in the echoclient xterm shows up in the netcat xterm. (The Windows netcat
seems to have some problem with newline when running against the echoclient examples connecting
from Linux. Sometimes I have to press enter to get the text to appear. The Linux netcat works perfect).


Anyway, I managed to make a gnet test program that spawns a thread for reading and writes from
another thread. This program works on both Windows and Linux. I tried it against netcat on both Linux
and Windows and against echoserver programs from the gnet examples (including a modified echoserver-async.c
sent to me by Hubert Sokolowski) on Linux. It works with all servers. But the implementation
does not feel as clean as the ones in the echoclient examples. I am sure this is not the way
gnet was ment to be used... Hubert suggested, in an off-list message, that this program can be made
to work without the extra thread, using the normal async mechanism in gnet.

Any suggestions?


/Albert


---8<---


/* Comments removed to make this mail shorter... */
#include <stdlib.h>
#include <glib.h>
#include <gnet.h>

/* UNUSED only works with gcc. Avoids warnings about unused variables. */
#define UNUSED __attribute__ ((unused))


static void async_client_connfunc(GTcpSocket * socket,
                                  GTcpSocketConnectAsyncStatus status,
                                  gpointer data);

G_LOCK_DEFINE(socket);
GTcpSocket *async_socket = NULL;
static GIOChannel *iochannel;
static GMainLoop *main_loop;


int main(int argc, char **argv)
{
   gchar *hostname;
   gint port;

   g_thread_init(NULL);

   gnet_init();

   /* Parse args */
   if (argc != 3) {
      g_print("usage: %s <server> <port>\n", argv[0]);
      exit(1);
   }
   hostname = argv[1];
   port = atoi(argv[2]);

   /* Create the main loop */
   main_loop = g_main_new(FALSE);

   /* Connect asynchronously */
   gnet_tcp_socket_connect_async(hostname, port, async_client_connfunc, NULL);

   /* Start the main loop */
   g_main_run(main_loop);

   return 0;
}


static void *read_thread(UNUSED gpointer data)
{
   gsize n;
   gchar *str = NULL;
   gboolean quit = FALSE;

   /* Loop until error occurs or "quit" is read */
   do {
      /* Read one line */
      if (gnet_io_channel_readline_strdup(iochannel, &str, &n) != G_IO_ERROR_NONE) {
         g_print("read_thread: readline error, quitting\n");
         goto read_thread_out;
      }

      if (str != NULL) {
         g_print("read_thread: %s\n", str);
         if(g_str_has_prefix(str, "quit")) {
            quit = TRUE;
         }
         g_free(str);
         str = NULL;
      }
   } while(!quit);

 read_thread_out:

   /* Lock socket semaphore to make sure other
    * thread is not writing while shutting down
    */
   G_LOCK(socket);
   /* Close connection */
   g_io_channel_shutdown(iochannel, TRUE, NULL);
   gnet_tcp_socket_unref(async_socket);
   async_socket = NULL;
   G_UNLOCK(socket);

   g_main_loop_quit(main_loop);

   return NULL;
}


static void
async_client_connfunc(GTcpSocket * socket,
                      GTcpSocketConnectAsyncStatus status, UNUSED gpointer data)
{
   gsize n;

   if (status != GTCP_SOCKET_CONNECT_ASYNC_STATUS_OK) {
      g_print("Error: Could not connect (status = %d)\n", status);
      exit(1);
   }

   async_socket = socket;

   /* Read from socket */
   iochannel = gnet_tcp_socket_get_io_channel(async_socket);

   /* Start read_thread (add check for errors here) */
   g_thread_create(read_thread,NULL, FALSE, NULL);

   /* Send test message over and over again */
   while (1) {
      if (iochannel) {
         /* Lock semaphore to avoid writing while read_thread is disconnecting */
         G_LOCK(socket);
         if (async_socket != NULL) {
            gnet_io_channel_writen(iochannel, "Hello, netcat!\n", 15, &n);
         } else {
            /* quit */
            g_print("async_client_connfunc: quitting\n");
            G_UNLOCK(socket);
            return;
         }
         G_UNLOCK(socket);
      }
      g_usleep(100000);
   }
}


--->8---

PS
 Totally unrelated. To get pkg-config to work with MinGW I made a small change in gnet-2.0.pc (absolute path
 changed to prefix). Modified file is attached to this mail.
DS

Attachment: gnet-2.0.pc
Description: gnet-2.0.pc



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