g_io_channel + socket = server , still just get one client ? in C language

送分小仙女□ 提交于 2019-12-11 17:37:42

问题


folks, here ma code :

#include <glib.h>
#include <gio/gio.h> // gio channel

#include <sys/socket.h> //socket();
#include <netdb.h> // structure

#include <stdio.h> // printf

void deal(GIOChannel *in, GIOCondition condition, gpointer data)
{
    struct sockaddr_storage income;

    int insock = g_io_channel_unix_get_fd(in);
    socklen_t income_len = sizeof(income);
    int newsock = accept(insock, (struct sockaddr*)&income, &income_len );
    if(newsock == -1)
    {
        printf("failure on newsock\n");
    }

    char buff[128];

    int recv_total = 0;
    int recv_byte = 128;
    int recv_sizing;

    while (recv_total < recv_byte ){

    recv_sizing = recv(newsock,buff + recv_total,recv_byte,0);

    // breaking if recv_sizing = -1 assuming as error, 0 assuming as lost communication from client suddenly
    if(recv_sizing < 0 || recv_sizing == 0)
     {
         printf("connection lost or error while recv(); [ just guess ] number : %d \n",recv_sizing);
         break;
    }

    recv_byte -= recv_sizing;
    recv_total += recv_sizing;


    }


    buff[recv_total] = '\0';
    //recv_sizing = recv(newsock,buff,recv_byte,0);
    printf("data : %s\n",buff);

    close(newsock); // close immediate and look for another some1 new


}

int main()
{
    GIOChannel *in;


    struct sockaddr_in my;
    my.sin_addr.s_addr = INADDR_ANY;
    my.sin_family      = AF_INET;
    my.sin_port        = htons(3000);

    //socket initiate root socket
    int rsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    //allow re-use address
    setsockopt(rsock,SOL_SOCKET,SO_REUSEADDR,(int*)1,sizeof(int));

    //binding
    bind(rsock,(struct sockaddr*)&my,sizeof(my));

    //listen
    listen(rsock,10);


    in = g_io_channel_unix_new(rsock);

    g_io_add_watch(in, G_IO_IN | G_IO_OUT | G_IO_HUP, (GIOFunc) deal, NULL);


    GMainLoop *loop = g_main_loop_new(NULL,FALSE); // pengganti while(1) ato gtk_main_loop
    g_main_loop_run(loop);
    return 0;
}

these is how it get compiled and running :

$ gcc -o dengersocket_glib dengersocket_glib.c `pkg-config --cflags --libs glib-2.0`
$ ./dengersocket_glib 

the client wanna try to send :

$ echo wew | nc -v localhost 3000 
nc: connect to localhost port 3000 (tcp) failed: Connection refused
Connection to localhost 3000 port [tcp/*] succeeded!

the server receiving :

$ ./dengersocket_glib 
connection lost or error while recv(); [ just guess ] number : 0 
data : wew

receiving ok, but when another client trying to connecting :

$ echo dor | nc -v localhost 3000 
nc: connect to localhost port 3000 (tcp) failed: Connection refused
Connection to localhost 3000 port [tcp/*] succeeded!

nothing happen on server, how to make server could accept more than one client ? do fd_set really needed on these case ?


回答1:


The type GIOFunc returns gboolean, not void. You're working around that by casting your function to GIOFunc when registering it as a callback.

Since your function doesn't return anything, the glib code calling it probably sees "FALSE" as the return value of the function. FALSE in glib means "I don't need to monitor this event source anymore", so while youre main loop is still running (you never call g_main_loop_quit()), it is not monitoring your socket anymore.

Implement GIOFunc correctly and your problem will probably go away.



来源:https://stackoverflow.com/questions/5206599/g-io-channel-socket-server-still-just-get-one-client-in-c-language

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!