g_io_channel + socket = client, и GIO не работают должным образом - PullRequest
0 голосов
/ 20 марта 2011

чувак, я собираюсь создать клиента и объединить его с каналом GIO, и после того, как я соберу все это вместе, кажется, что он работает на сокете, но g_io_channel не так смотрит, как сбой или что-то в этом роде.

см. следующий код:

#include <stdio.h>
#include <gio/gio.h> // g_timeout_add
#include <gtk/gtk.h> // gtk 
#include <netinet/in.h> //sockaddr_in
#include <sys/socket.h> // socket();
#include <arpa/inet.h> // inet_addr();
#include <string.h> // memset();


struct dada
{
    gint id_sock;
    guint id_gio_watch;
};




gboolean incoming(GIOChannel *chan, GIOCondition condition, struct dada *didi )
{
    int byte;

    int insock = g_io_channel_unix_get_fd(chan);

    #define MAXMAX 128
    char buff[128];

    printf("sock : %d\n",insock);

    byte = recv(insock,buff,MAXMAX-1,0);

    if(byte <= 0)
    {
        perror("recv");
        close(didi->id_sock);
        g_source_remove(didi->id_gio_watch);
        return FALSE;
    }
    else
    {
        buff[byte] = '\0';
        printf("coming : %s",buff);
    }

    return TRUE;
}


// gtk area

void hello(GtkWidget *widget, gpointer data)
{
    g_print("Haii world  %s\n", (char *)data);

}


gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    g_print("a delete event has been occured properly :D\n");

    return(0);  
}

void destroy(GtkWidget * widget, gpointer data)
{
    gtk_main_quit();  
}
// end of gtk area



int main(int argc, char **argv)
{

    //gtk bussines from here
      GtkWidget *window;
    GtkWidget *button;

     gtk_init(&argc,&argv);
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);
    gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(window),10);

    button = gtk_button_new_with_label("ohayo");

    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(hello), (gpointer)"hha" );
    gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));

    gtk_container_add(GTK_CONTAINER(window),button);

    gtk_widget_show(button);
    gtk_widget_show(window);

    //gtk bussiness done here...


    // network code //
    struct dada didi;
    memset(&didi,0,sizeof(didi));

    struct sockaddr_in my; // set my network device info
    gint rootsock;         // handle the root socket

    //socket
    rootsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    //binding
    memset(&my,0,sizeof(my));
    my.sin_addr.s_addr = inet_addr("127.0.0.1");
    my.sin_family      = AF_INET;
    my.sin_port        = htons(1111);
    //bind(rootsock,(struct sockaddr*)&my,sizeof(my));

    printf("sock : %d\n",rootsock);
    connect(rootsock,(struct sockaddr*)&my,sizeof(my));

    didi.id_sock = rootsock;
    didi.id_gio_watch = g_io_add_watch(g_io_channel_unix_new(didi.id_sock),G_IO_IN|G_IO_OUT,(GIOFunc)incoming,&didi);

    // network code //

     gtk_main();





    return 0;






}

компиляция:

$ gcc -o konek_gioglib konek_gioglib.c `pkg-config glib-2.0 --libs --cflags gtk+-2.0`

мой собственный компьютер работает как сервер с портом 1111 и потоковым соединением (TCP):

$ nc -v -l 1111

запустив мое приложение:

$ ./konek_gioglib
sock : 6
sock : 6

сервер получил соединение и отправил какое-то слово:

$ nc -v -l 1111
Connection from 127.0.0.1 port 1111 [tcp/*] accepted
a
a

и когда сервер что-то отправил, окно gtk показывается, но с ошибкой, подобной этой:

enter image description here

Кто-нибудь не против объяснить, почему эти вещи могли случиться с моими?

1 Ответ

3 голосов
/ 22 марта 2011

хорошо прошлой ночью я провел мозговой штурм своим собственным сердцем, и, наконец, смог заставить все это работать,

здесь правильный код

#include <stdio.h>
#include <gio/gio.h> // g_timeout_add
#include <gtk/gtk.h> // gtk
#include <netinet/in.h> //sockaddr_in
#include <sys/socket.h> // socket();
#include <arpa/inet.h> // inet_addr();
#include <string.h> // memset();
#include <fcntl.h>
#include <stdlib.h>

struct dada
{
    gint id_sock;
    guint id_gio_connect;
    guint id_gio_watch;
};


gboolean readdata(GIOChannel *chan,GIOCondition condition, struct dada *didi)
{

  gchar dada[20] = {0};
  int dadaz =0;


 if( condition != G_IO_IN )
    return FALSE;



  if(dadaz = recv(g_io_channel_unix_get_fd(chan),dada,19,0)<=0)
  {
      perror("recv");
      close(didi->id_sock);
      g_source_remove(didi->id_gio_connect);
      g_source_remove(didi->id_gio_watch);
      exit(0);
      return FALSE;
  }

      printf("data in : %s\n",dada);




         return TRUE;
}


gboolean incoming(GIOChannel *chan, GIOCondition condition, struct dada *didi )
{


     if( condition & G_IO_ERR || condition & G_IO_HUP )
     return FALSE;


    didi->id_gio_watch = g_io_add_watch(chan,G_IO_IN | G_IO_ERR | G_IO_HUP,(GIOFunc)readdata,didi);


    return FALSE;
}


// gtk area

void hello(GtkWidget *widget, gpointer data)
{
    g_print("Haii world  %s\n", (char *)data);

}


gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
    g_print("a delete event has been occured properly :D\n");

    return(0);
}

void destroy(GtkWidget * widget, gpointer data)
{
    gtk_main_quit();
}
// end of gtk area



int main(int argc, char **argv)
{

    //gtk bussines from here
      GtkWidget *window;
    GtkWidget *button;

     gtk_init(&argc,&argv);
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);
    gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(destroy), NULL);
    gtk_container_set_border_width(GTK_CONTAINER(window),10);

    button = gtk_button_new_with_label("ohayo");

    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(hello), (gpointer)"hha" );
    gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));

    gtk_container_add(GTK_CONTAINER(window),button);

    gtk_widget_show(button);
    gtk_widget_show(window);

    //gtk bussiness done here...


    // network code //
    struct dada didi;
    memset(&didi,0,sizeof(didi));

    struct sockaddr_in  your; // set my network device info
    gint rootsock;         // handle the root socket

    //socket
    rootsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);



    memset(&your,0,sizeof(your));


    printf("sock : %d\n",rootsock);

    your.sin_family = AF_INET;
    your.sin_addr.s_addr = inet_addr("127.0.0.1");
    your.sin_port   =   htons(1111);

    connect(rootsock,(struct sockaddr*)&your,sizeof(your));

    didi.id_sock = rootsock;
    didi.id_gio_connect = g_io_add_watch(g_io_channel_unix_new(didi.id_sock),G_IO_IN | G_IO_OUT | G_IO_ERR | G_IO_HUP,(GIOFunc)incoming,&didi);

    // network code //

     gtk_main();





    return 0;






}

, и единственное, что я сделал, это "сработал "код, нужно:

- gio for connecting, and gio for watching

вместо того, чтобы быть" нерабочим "кодом (only gio for connecting), но опять-таки мне просто интересно," почему ", почему на connect () нужно два gio (рекурсивно)для того, чтобы заставить эти "вещи gio" работать,

это действительно странно, если я увижу то, что на g_io_channel + socket = server, все еще только один клиент?на языке C

для которого на accept () нужен только один gio и только для просмотра.

если кто-то может объяснить это, как здорово это будет:)

...