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

Reply via email to