g_io_channel + socket = 服务器,仍然只得到一个客户端?用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;
}
这是它的编译和运行方式:
$ 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
接收正常,但是当另一个客户端尝试连接时:
$ 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 吗?
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 ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
GIOFunc 类型返回 gboolean,而不是 void。您可以通过在将函数注册为回调时将其转换为 GIOFunc 来解决这个问题。
由于您的函数不返回任何内容,因此调用它的 glib 代码可能会将“FALSE”视为函数的返回值。 Glib 中的 FALSE 意味着“我不再需要监视此事件源”,因此当您的主循环仍在运行时(您从不调用 g_main_loop_quit()),它不再监视您的套接字。
正确实施 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.
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.