GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Sun Aug 31, 2014 6:15 am

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Re: Gtk + timer + sockets + cairo
PostPosted: Wed Feb 29, 2012 6:43 am 
Offline
Familiar Face

Joined: Thu Dec 15, 2011 6:23 pm
Posts: 36
Location: Hrvatska
common way to use socket is to open GIOChannel and then add watch - asynchron function. here is my sample - I use UDP datagram, but you can easy change to TCP stream as well.
Code:
gboolean
init_udp_server ()
{
   struct sockaddr_in ip4addr;        // socket address
   // struct hostent     *he;            // host
   GError *err = NULL;

   sock = g_socket_new(G_SOCKET_FAMILY_IPV4,
                       G_SOCKET_TYPE_DATAGRAM,
                       G_SOCKET_PROTOCOL_UDP,
                       &err);
   if (err)
   {
         g_error_free (err);
         g_print (" %s\n", err->message);
         return TRUE;
   }
   // g_assert(err == NULL);

   /*
   if ((he = gethostbyname("localhost")) == NULL)
   {

       g_print ("gethostbyname() error !");
       return;
   }
   */
   ip4addr.sin_family = AF_INET;
   ip4addr.sin_port   = htons(4950);                           // listen port
   inet_pton (AF_INET, "192.168.1.101", &ip4addr.sin_addr);      // source address
   // ip4addr.sin_addr = *((struct in_addr *)he->h_addr);         // listen at host addres
   memset(&(ip4addr.sin_zero), '\0', 8);
   GSocketAddress *addr = g_socket_address_new_from_native (&ip4addr, sizeof ip4addr);

   g_socket_bind(sock,
                 G_SOCKET_ADDRESS (addr),
                 TRUE,
                 &err);
   if (err)
   {
         g_error_free (err);
         g_print (" %s\n", err->message);
         return TRUE;
   }
   // g_assert(err == NULL);

   g_socket_set_blocking (sock, FALSE);

   // we already BIND source, now DEST addr
   ip4addr.sin_family = AF_INET;
   ip4addr.sin_port   = htons(4951);                           // send to port
   inet_pton (AF_INET, "192.168.1.102", &ip4addr.sin_addr);      // dest address
   memset(&(ip4addr.sin_zero), '\0', 8);
   dest_addr = g_socket_address_new_from_native (&ip4addr, sizeof ip4addr);

   cancel = g_cancellable_new ();            // za potrebe send_to

      /*
      To get an event when the socket receives data, the following steps are necessary:

          Get a file descriptor for the socket.
          Use the file descriptor to create a GIOChannel for the socket.
          Add a watch for the G_IO_IN condition on the channel.
      */

   int fd = g_socket_get_fd(sock);
   GIOChannel *channel = g_io_channel_unix_new(fd);

   guint source = g_io_add_watch(channel, G_IO_IN,
                                (GIOFunc) recv_cb_func, NULL);


   g_io_channel_unref(channel);
   g_object_unref (addr);
   return FALSE;

      /*
       * GIOFunc must not block
       * Cleaning up is pretty simple: Use g_source_remove(source) to disconnect the event source
       * and g_object_unref() the objects.
       */

}


after that init part, you need GIOFunc , I call it RECV_CB_FUNC . It can look something like this:

Code:
// Callback for UDP listener , GIOFunc
static gboolean
recv_cb_func (GIOChannel *source, GIOCondition *cond, gpointer dta)
{
   gchar *buffer = (gchar *) g_malloc0 (128);
   GError    *error = NULL;
   gsize size = 86;
   gssize b_read = 0;

   b_read = g_socket_receive (sock, buffer, size, NULL, &error);

   if (error)
   {
         g_print (" %s\n", error->message);
         g_error_free (error);
         g_free (buffer);
         return FALSE;      // close CHANNEL !
   }

   g_print("Got: %d: %s\n", b_read, buffer);
   if (b_read == 86)
   {
             // length 86 bytes for data payload of UDP packet
            // do something

                 recv_paket = TRUE;
         
        } // total 86 ok

   g_free (buffer);
   return TRUE;    // source remain open
}


here I set RECV_PAKET flag to TRUE - so I can do more in main loop. You can process received data immidietly, or just set some flags, it is up to you. If you work with TCP stream, you will change a way to handle stream of data.
This is just a piece of code, hope it can help.
Some day I will put complete sample in PROJECTS forum ;)
Cheers !


Top
 Profile  
 
 Post subject: Re: Gtk + timer + sockets + cairo
PostPosted: Wed Feb 29, 2012 12:00 pm 
Offline
Never Seen the Sunlight

Joined: Thu Mar 24, 2011 2:10 pm
Posts: 328
Location: Sydney, Australia
Just an adendum, you have a lot of unnecessary includes as gtk wraps in a lot of libraries which have duplicate functionity of most of your libraries (and some are even implemented cross-platform much better). cairo.h is automatically included with gtk. Also if your using glib's functionality you won't need stdio and string etc. and you get G_PI defined too (its 3.1416 to 4 sig.figs. by the way, but that will hardly make a difference for rendering a circle)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group