g_io_channel +套接字=服务器,仍然只获得一个客户端?用C语言 [英] g_io_channel + socket = server , still just get one client ? in C language

查看:144
本文介绍了g_io_channel +套接字=服务器,仍然只获得一个客户端?用C语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

人们, 这里是代码:

#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 

客户想要尝试发送:

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

服务器接收:

$ ./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!

服务器上什么也没有发生,如何使服务器可以接受多个客户端?在这种情况下真的需要fd_set吗?

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

推荐答案

GIOFunc类型返回gboolean,而不是void.您正在通过将函数注册为回调时将其强制转换为GIOFunc来解决此问题.

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

由于您的函数未返回任何内容,因此调用该函数的glib代码可能会将"FALSE"视为该函数的返回值. glib中的FALSE表示我不再需要监视此事件源",因此,当您的主循环仍在运行时(您永远不会调用g_main_loop_quit()),它将不再监视您的套接字.

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.

正确实施GIOFunc,您的问题可能会消失.

Implement GIOFunc correctly and your problem will probably go away.

这篇关于g_io_channel +套接字=服务器,仍然只获得一个客户端?用C语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆