i attached the code but did not make thru, here is the server code: GMTCPServer *tcp_server_new(const Configurations *p_configurations) { GMTCPServer *new_server; GError *error = NULL; int fd;
// create a new tcp server object new_server = g_new(GMTCPServer,1); // get the configurations reference new_server->configurations = p_configurations; // create the context for this thread new_server->context = g_main_context_new(); // initialize the list of clients new_server->clients_list = g_ptr_array_new_with_free_func((void*)gm_connection_destroy); // create the server socket fd = tcp_server_listerner_new(new_server->configurations,&error); if(fd < 0) { g_error("Could not create listener, server creation aborted: %s",error->message); g_error_free(error); return NULL; } // create the GIOChannel for the server socket new_server->socket = g_io_channel_unix_new(fd); // set the encoding safe to read binary data on the server GIOChannel g_io_channel_set_encoding(new_server->socket,NULL,NULL); // create a source for connection events on the server socket new_server->event_source = g_io_create_watch(new_server->socket,G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL); // set the callback function to handle connection events g_source_set_callback(new_server->event_source,(GSourceFunc)tcp_server_handle_connection_events,new_server,NULL); // attach the server socket connection event source to the server context g_source_attach(new_server->event_source,new_server->context); // create the callback event source new_server->callback_source = async_callback_new(); // attach the callback event source to the context g_source_attach(new_server->callback_source,new_server->context); // create the main loop for this thread new_server->main_loop = g_main_loop_new(new_server->context,FALSE); // the thread will be started later new_server->server_thread = NULL; return new_server; } void tcp_server_destroy(GMTCPServer *p_server) { g_message("Destroying GoMobile server ..."); // quit the main loop g_main_loop_quit(p_server->main_loop); // join the server thread if(p_server->server_thread != NULL) { g_thread_join(p_server->server_thread); } // remove the server socket connection event source from the context g_source_destroy(p_server->event_source); // remove callback event source from the server context g_source_destroy(p_server->callback_source); // close and free server socket resources g_io_channel_shutdown(p_server->socket,TRUE,NULL); // close all client connections g_ptr_array_free(p_server->clients_list,TRUE); // free resources associated with event source g_source_unref(p_server->event_source); // free resources associated with the callback event source g_source_unref(p_server->callback_source); // free the resources in the server socket g_io_channel_unref(p_server->socket); // destroy the main loop g_main_loop_unref(p_server->main_loop); // free the context resources g_main_context_unref(p_server->context); // delete the memory allocated by the tcp object itself g_free(p_server); g_message("Done"); } void tcp_server_run(GMTCPServer *p_server) { // run the main loop now g_main_loop_run(p_server->main_loop); g_thread_exit(NULL); } int tcp_server_listerner_new(const Configurations *p_configurations,GError **p_error) { int fd; struct sockaddr_in servAddr; int set_option = 1; // create the socket fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(fd < 0) { *p_error = g_error_new(G_IO_CHANNEL_ERROR,G_IO_CHANNEL_ERROR_FAILED,"Could not create server socket: %s",strerror(errno)); return -1; } // set some options on the socket fcntl(fd,F_SETFL,O_NONBLOCK);// set the socket non-blocking setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&set_option,sizeof(set_option));// reuse address setsockopt(fd,SOL_SOCKET,SO_KEEPALIVE,&set_option,sizeof(set_option));// send keep alive messages // construct local address structure memset(&servAddr,0x00, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(p_configurations->tcp_server.interface); servAddr.sin_port = htons(p_configurations->tcp_server.port); // Bind to the local address if(bind(fd,(struct sockaddr*)&servAddr,sizeof(servAddr)) < 0) { *p_error = g_error_new(G_IO_CHANNEL_ERROR,G_IO_CHANNEL_ERROR_FAILED,"Could not bind server socket: %s",strerror(errno)); // close the socket close(fd); return -1; } if(listen(fd,10) < 0) { *p_error = g_error_new(G_IO_CHANNEL_ERROR,G_IO_CHANNEL_ERROR_FAILED,"Could not start listening on the server socket: %s",strerror(errno)); // close the socket close(fd); return -1; } return fd; } gboolean tcp_server_handle_connection_events(GIOChannel *p_source,GIOCondition p_condition,GMTCPServer *p_server) { TCPClientConnection *client = NULL; struct sockaddr_in sockaddr; socklen_t client_fd_len; int client_fd; // GError *error = NULL; int set_option = 1; if(p_condition & (G_IO_IN|G_IO_PRI)) { // accept the connection now client_fd_len = sizeof(sockaddr); if((client_fd = accept(g_io_channel_unix_get_fd(p_server->socket),(struct sockaddr*)&sockaddr,&client_fd_len)) < 0) { g_error("Could not accept new connection: %s",strerror(errno)); return TRUE; } fcntl(client_fd,F_SETFL,O_NONBLOCK);// set the socket non-blocking setsockopt(client_fd,SOL_SOCKET,SO_KEEPALIVE,&set_option,sizeof(set_option));// send keep alive messages g_message("New connection attempt"); // create a client connection client = gm_connection_new(client_fd,p_server); // get the address for this client if (inet_ntop(AF_INET,&sockaddr.sin_addr.s_addr,client->ip,sizeof(client->ip)) != NULL) { client->port = ntohs(sockaddr.sin_port); g_message("Successfully accepted new client connection from %s:%d",client->ip,client->port); } else { client->ip[0] = 0; client->port = -1; g_message("Successfully accepted new client connection from an unknown location"); } // run the connection thread client->connection_thread = g_thread_create((GThreadFunc)gm_connection_run,client,TRUE,/*&error*/NULL); if(client->connection_thread == NULL) { g_error("Could not start new connection for client: %s:%d, will end this connection",client->ip,client->port); gm_connection_destroy(client); } else { // push it into the client array g_ptr_array_add(p_server->clients_list,client); g_message("Successfully started new connection"); } return TRUE; } // an error happened // show an error message and try to get a description from errno g_warning("An error occurred on the server socket: %s",strerror(errno)); return TRUE; } gboolean tcp_server_remove_connection(TCPClientConnection *p_client) { // remove a client g_ptr_array_remove(p_client->my_server->clients_list,p_client); return TRUE; } and the server is astarted only once from the main thread. regarding GIO, i like to have like control of things so i m just sticking with glib, what i need from glib are the special structucures like array pointers, sometimes the strings as containers and of course, the mail loop :) .... > Date: Fri, 22 Oct 2010 10:17:30 +0100 > From: ch...@cvine.freeserve.co.uk > To: jpablolorenze...@hotmail.com > CC: maginot.jun...@gmail.com; gtk-app-devel-list@gnome.org > Subject: Re: poll with timeout 0 in main loop > > On Fri, 22 Oct 2010 02:57:59 +0000 > Juan Pablo L. <jpablolorenze...@hotmail.com> wrote: > > hi, this is the code that makes the server socket > [snip] > > There doesn't seem anything especially wrong with this but you have a > lot of code missing. In particular, what does your > tcp_server_handle_connection_events() callback do, such as when it > encounters errors (you specify that the callback is to be entered in a > case of G_IO_NVAL and G_IO_ERR), and how do you disconnect sources from > the main loop when they are finished with (I notice also you don't > unref the sources after attaching them to the main loop). Quite > possibly you are looping in a case of errors or defunct sources. > > Probably the best thing you can do is come up with the smallest test > case which demonstrates the error (with say just one socket worker > thread) and post it here. > > This is off topic, but glib's gio makes it trivial to construct new > server threads and it does all the hard stuff for you, but you need > glib version 2.22 for gio's socket API. Glib's gio has no relationship > with GIOChannels, despite the similar names. > > Chris _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list