Re: GIO channels and "connection closed by foreign host" on WIN32



On Tue, Mar 17, 2009 at 4:26 PM, Tor Lillqvist <tml iki fi> wrote:
Do you have a minimal but complete sample program that exhibits the problem?

--tml


Here it is, I've made it as minimal as a crossplatform gtk socket
program can be, the code may give a pair of warnings and passes the fd
as userdata, this is to "mimic" the real code that passes a class base
pointer that contains also the FD and to specify that the code doesn't
use gio channels API to get FD or read/write.

It compiles both on win32 and linux, command line on linux for both builds:

Linux native:
gcc -o t test.c `pkg-config gtk+-2.0 --cflags --libs`

WIN32 cross:
/usr/i586-mingw32msvc/bin/gcc -o test.exe -gstabs
-I/usr/i586-mingw32msvc//include/glib-2.0
-I/usr/i586-mingw32msvc//lib/glib-2.0/include/
-I/usr/i586-mingw32msvc//include/cairo
-I/usr/i586-mingw32msvc//include/gtk-2.0
-I/usr/i586-mingw32msvc//include/atk-1.0
-I/usr/i586-mingw32msvc//include/pango-1.0
-I/usr/i586-mingw32msvc//lib/gtk-2.0/include -mno-cygwin
-mms-bitfields -DOOGTK_DEBUG socktest.c
-L/usr/i586-mingw32msvc//lib/gtk-2.0 -lgtk-win32-2.0 -lgdk-win32-2.0
-latk-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lpangowin32-1.0 -lgmodule-2.0
-lgobject-2.0 -lgthread-2.0 -lglib-2.0 -luser32 -lws2_32

How to reproduce:
On a linux server machine type (say with address 192.168.1.10):
nc -vlp 4000

On a client machine (if win32 you should run it from a cmd since it
does most of this output on stderr):
test 192.168.1.10 4000

Now type something in the shell where you launched netcat ("hello"
<enter>, "hi" <enter>...)

You should see the label of the gtk program update.

Last step, the one where the problem is, close netcat with CTRL+C.

If the gtk client is linux it will disconnect.
*** If the gtk client is win32 it will not receive any error ***

Test is done both on win32 and linux with GTK 2.14.x (latest version
before the 2.16 stable).

Source:

#include <gtk/gtk.h>
#include <stdlib.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#endif

GtkWidget *label;
void cbk(GIOChannel *c, int cond, int fd)
{
    char buffer[1024];
    int rc = recv(fd, buffer, sizeof(buffer), 0);
    if (rc == 0) {
        fprintf(stderr, "Connection closed\n");
        gtk_main_quit();
    }
    else if (rc < 0) {
        fprintf(stderr, "Error handling removed!\n");
        gtk_main_quit();
    }
    else {
        fprintf(stderr, "Received %d bytes\n", rc);
        buffer[rc] = 0;
        gtk_label_set_text(GTK_LABEL(label), buffer);
    }
}
int main(int argc, char *argv[])
{
    GtkWidget *w;
    GIOChannel *ch;
    struct sockaddr_in addr;
    int fd;
    if (argc != 3) {
        fprintf(stderr, "Use %s host port\n", argv[0]);
        exit(0);
    }
#ifdef WIN32
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD( 2, 0 ), &wsaData) != 0) return;
#endif
    gtk_init(&argc, &argv);
    w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    label = gtk_label_new(NULL);
    gtk_container_add(GTK_CONTAINER(w), label);

    fd = socket(AF_INET, SOCK_STREAM, 0);
    memset((void*)&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);

    if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        fprintf(stderr, "Error in connect to %s/%d!\n", argv[1], atoi(argv[2]));
        exit(0);
    }
#ifdef WIN32
    ch = g_io_channel_win32_new_socket(fd);
#else
    ch = g_io_channel_unix_new(fd);
#endif
    g_io_add_watch(ch, G_IO_IN, cbk, fd);
    gtk_widget_show_all(w);
    gtk_main();
}

--
Bye,
 Gabry



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