伙计们请看以下代码:
#include <gio/gio.h>
#include <sys/socket.h> //socket();
#include <netinet/in.h> //sockaddr_in
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define RECV_SIZE_MODE 1024 // mmmm
typedef struct _unit_
{
gint sockmax;
fd_set client,client_tmp;
} _unit;
gboolean network_deal_api(GIOChannel *in,GIOCondition condition, _unit *unit)
{
struct sockaddr_storage income;
unit->client_tmp = unit->client;
gint i;
//enum client
gchar ip[INET_ADDRSTRLEN];
guint port;
//convert
gint insock = g_io_channel_unix_get_fd(in);
//prepare for new income
socklen_t income_len = sizeof(income);
gint newsock;
//something come in
char buffer_in[RECV_SIZE_MODE] = {0};
gint recv_sizing;
switch(condition)
{
case G_IO_IN:
for(i=0; i <= unit->sockmax; i++)
{
if(FD_ISSET(i,&unit->client_tmp)) //something coming through handler inside client_tmp, we'll see if the socket has suppose to be someone own
{
printf("process on socket number : %d\n",i);
if(i == insock) // if handler of socket(); then create new accept handler, if these is a handler of accept();, then else which mean 'incoming data'
{
newsock = accept(insock,(struct sockaddr*)&income, &income_len);
if(newsock == -1)
{
printf("failure once getting new socket\n");
return FALSE;
}
else
{
FD_SET(newsock, &unit->client);
if(newsock > unit->sockmax)
{
unit->sockmax = newsock;
}
inet_ntop(income.ss_family,&((struct sockaddr_in*)&income)->sin_addr,ip,INET_ADDRSTRLEN);
port = htons(((struct sockaddr_in*)&income)->sin_port);
printf("connected to : %s:%d on socket : %d\n",ip,port,newsock);
}
}
else
{
if(recv_sizing = recv(i,buffer_in,RECV_SIZE_MODE,0) <= 0)
{
if(recv_sizing == 0)
{
printf("socket %d hung up\n",i);
}
if(recv_sizing == -1)
{
perror("recv");
}
close(i);
FD_CLR(i,&unit->client);
}
buffer_in[recv_sizing-1] = '\0';
printf("data in : %s length : %d\n",buffer_in,strlen(buffer_in));
}
}
}
break;
}
}
int main()
{
_unit *unit = (_unit*)malloc(sizeof(_unit));
struct sockaddr_in my; // set my network device info
gint rootsock; // handle the root socket
GIOChannel *in_handle;
guint in_handle_watching; // whether the watching event intend to remove
FD_ZERO(&unit->client); // initiate
FD_ZERO(&unit->client_tmp);
//let construct a server
//socket
rootsock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//binding
memset(&my,0,sizeof(my));
my.sin_addr.s_addr = INADDR_ANY;
my.sin_family = AF_INET;
my.sin_port = htons(1111);
bind(rootsock,(struct sockaddr*)&my,sizeof(my));
//set the queue, let say for commonly situation 10
listen(rootsock,10);
FD_SET(rootsock,&unit->client);
unit->sockmax = rootsock; //so far its this one
in_handle = g_io_channel_unix_new(rootsock); // handed socket to channel
in_handle_watching = g_io_add_watch(in_handle,G_IO_IN|G_IO_OUT,(GIOFunc)network_deal_api,unit);
printf("server listening on : %d\n",ntohs(my.sin_port));
printf("look forward for any new income connection\n");
GMainLoop *loop = g_main_loop_new(NULL,FALSE);
g_main_loop_run(loop);
free(unit);
return 0;
}
并编译并运行:
$ gcc -o multiplechat_gio multiplechat_gio.c `pkg-config --libs --cflags gio-2.0`
$ ./multiplechat_gio
server listening on : 1111
look forward for any new income connection
有人远程登录它:
$ telnet localhost 1111
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
tes
aja
deh
^C
以及为什么服务器不显示数据包(只有在其他人连接到服务器时才显示数据包)?
$ ./multiplechat_gio
server listening on : 1111
look forward for any new income connection
process on socket number : 3
connected to : 127.0.0.1:48814 on socket : 4
那怎么了?任何人 ?