Saturday, August 27, 2016

GLIB/GTK+3 Network Programming using UDP on the Raspberry Pi





My plan was to create a CommandLine and GTK based Display service for use with my Raspberry Pi projects.  I already have a GitHub package that includes a node Registry for locating existing Pis on the network.  This registry also contains a list of network based services, like the display service I’m planning to write.

The usage model assumes you’ve written some program that collects data from the many different sensors available to the Raspberry Pi, like temperature sensors, ultrasonic distance sensors. Etc.   When writing these sensor programs, displaying the output would be helpful, but continuously writing the display routines is distracting.  This is where the display service programs come into play; it makes displaying sensor results easier to implement and defines a network model that allows you to build other network services using the existing registry.

I choose UDP as the transport protocol to acknowledge the unreliable behaviors present in Internet of Things (IOT) devices and platforms.  For me this means, that one of my Pis (which is providing a service) may not be working or online and I don’t want its absence to hang up my primary program.  UDP allows us to send requests which we hope will be serviced, but it won’t be the end of the world if there not!

I have a fair amount of GTK+2 and GLIB programming experience and thought using the newer versions of both would be an interesting exercise, and also shorten the development time.  Version GTK+3 and GLIB+2 was my choice.  Turns out that if I were not using UDP that assertion would have been true.  Glib does support UDP with several workable and helpful improvements.  However, the actual methods were difficult to identify and several trials failed because of the mechanics of UDP versus TCP.  I tried and wanted to use the high-level networking APIs GLIB provides like GSocketClient, GSocketService, GThreadedSocketService, and GIOChannels only to discover that they are TCP specific and don’t support UDP; at lest in the fashion I was planning to use them.  The primary tell was the inclusion of a ‘Listen’ or ‘Listener’ API.  

TCP, being session based, includes the listener as a regular feature of the session building process; GLIB’s high-level networking APIs automate the invocation of the listener and sometimes bind operation as part of their high-level notion.  The listener api is not needed for UDP since we never create a session between the communication partners.  Invoking a listener on a UDP socket immediately produces an error.  No worries though, the GSocket API fully supports both TCP and UDP communications.  Using a handful of the GSocket grouped APIs.  I was able to create a polished command line version of this display service in less than 150 lines of C code.

GLIB includes many advanced and simplified programming facilities, and is also the underlying support for the graphics library GTK+.  To provide a graphical UI for my display service, I will use GTK/GLIB to implement it.  One key feature of GLIB that was interesting to me was its Event Loop.  A facility that allows all UI and IO related events to be continuously serviced without overly complex synchronization strategies, keep the UI responsive while managing the IO polling needed to support both of my planned operations; UDP network communications and graphical UI events.

Many more details to layout, but we have a working example in the github project referenced above.




No comments:

Post a Comment