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

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]