Help with GIOChanel on Win32 - How do I know that a socket was closed?



Hello.

I'm trying to use GIOChannels, but I probably didn't understand the proper way to use them (or is it a bug?).

Using:
   g_io_add_watch(io,
        G_IO_IN | G_IO_PRI | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
        foo,
        NULL);

should call my callback (foo) when the connection finishes, right? But it never gets called when the connection ends.
My code is bellow.

I'm using Win 98 SE, MinGW/GCC 3.3.1, latest GLib from Tor's site.



Daniel K. O.


----------- code ----------------
#include <stdlib.h>
#include <glib.h>
#include <winsock2.h>


SOCKET do_winsock_stuffs(const char *server);
void do_glib_stuffs(int s);

int main(int argc, char *argv[])
{
       const char * server = "rolex.peachnet.edu";
       SOCKET s;

       if (argc<2)
               g_print("Using default\n");
       else
               server = argv[1];

       g_print("Press 'Q' to exit\n");
       g_print("Server: %s\n", server);

       s = do_winsock_stuffs(server);

       /* now, let's use GLib's stuffs */
       do_glib_stuffs(s);

       g_print("We're done\n");
       system("PAUSE");

       return 0;
}

SOCKET do_winsock_stuffs(const char *server)
{
       struct hostent *phe;
       struct servent *pse;
       struct protoent *ppe;
       struct sockaddr_in sin;
       WSADATA wsa;
       SOCKET s;
WSAStartup(MAKEWORD(2, 0), &wsa);
       atexit((void(*)(void))WSACleanup);


       memset(&sin, 0, sizeof sin);
       /* set the address family... */
       sin.sin_family = AF_INET;
       /* ... the port ... */
       if (pse = getservbyname("TCP", "daytime"))
               sin.sin_port = pse->s_port;
       else
               sin.sin_port = htons( 13 );
       /* ... and the address */
       if (phe = gethostbyname(server)) {
               /* resolved */
               memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
       } else {
               /* probably is in x.x.x.x form */
               sin.sin_addr.s_addr = inet_addr(server);
               g_assert(sin.sin_addr.s_addr != INADDR_NONE);
       }

       g_print("Connecting...");
       ppe = getprotobyname("TCP");
       g_assert(ppe);

       /* Many people use AF_INET here, but it's WRONG! */
       s = socket(PF_INET, SOCK_STREAM, ppe->p_proto);
       g_assert(s!=INVALID_SOCKET);


       connect(s, (SOCKADDR*)&sin, sizeof sin);
       g_print("OK\n");
       return s;
}




gboolean foo(GIOChannel *source, GIOCondition condition, gpointer data)
{
       char buffer[1024];
       int len;
       GIOStatus status;

       g_assert(condition); /* 0 is an invalid condition */

       if (condition & G_IO_IN) {
               status = g_io_channel_read_chars(source, buffer,
                               sizeof buffer - 1, &len, NULL);
               if (status != G_IO_STATUS_NORMAL) {
                       g_print("Connection error: reading - status: %d\n",
                               status);
                       g_io_channel_shutdown(source, FALSE, NULL);
                       g_io_channel_unref(source);
                       return FALSE;
               }
               buffer[len] = '\0';
               g_print("Read: \"%s\"\n", buffer);
       }
if (condition & G_IO_ERR) {
               g_print("Connection error\n");
               g_io_channel_shutdown(source, FALSE, NULL);
               g_io_channel_unref(source);
               return FALSE;
       }
if (condition & G_IO_HUP) {
               g_print("Connection was closed\n");
               g_io_channel_shutdown(source, FALSE, NULL);
               g_io_channel_unref(source);
               return FALSE;
       }

       g_print("Condition: %d\n", condition);

       return TRUE;
}

gboolean bar(gpointer data)
{
       if (kbhit()) {
               int c = getch();
               if (c=='q' || c=='Q') {
                       GMainLoop *loop = data;
                       g_main_loop_quit(loop);
               }
       }
       return TRUE;
}

void do_glib_stuffs(int s)
{
       GIOChannel *io;
       GMainLoop *loop;
loop = g_main_loop_new(NULL, FALSE);

       io = g_io_channel_unix_new(s);

g_io_add_watch(io, G_IO_IN | G_IO_PRI | G_IO_NVAL | G_IO_ERR | G_IO_HUP , foo, NULL);
       g_io_channel_unref(io);

       g_idle_add(bar, loop);

       g_main_loop_run(loop);
}
------------





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