Back to Index

Maemo for mobile developers

Network programming using sockets

Table of contents

  1. Introduction
  2. Client/server socket example
  3. Client implementation
  4. Server implementation

Introduction

Sockets are interprocess communication interfaces that can also be used for network communication. For example, client-server applications can be written using sockets.

On maemo, you can use the Glib library to make the sockets implementation easier. Using the Glib::IOChannel class, you can integrate your sockets' I/O operations to the main event loop. This way your application doesn't need to keep polling the socket descriptor to be aware when a message is ready to be sent or read.

This section explains how to create a simple TCP (streamed) socket connection between two applications, client and server. These applications communicate with each other using sockets and use I/O channels to manage the incoming and outgoing messages.

Note: I/O channels can be used with other file descriptors besides sockets, such as files and pipes. The main goal of using I/O channels is that they do not block your application waiting for I/O operations because they are well integrated in the Glib main loop.

Client/server socket example

The server initializes with a given port specified by the user:

Server setup

The client starts and asks the user about the server IP address and port number of the server:

Client setup

After this, the client tries to connect to the server and if everything is correct, the server waits until a new message from the client arrives:

Server waiting

After connecting, the client shows the user an entry box for writing a message to be sent to the server:

Client message entry

The server gets the message sent by the client and displays it on the screen:
Server received message

Next, the source code of both applications is discussed. Client source code is explained first, since it is simpler than server source code.

Client application

This section explains some parts of the source code related to sockets and I/O channels operation. Below is the header for the Connection class. It contains the following new attributes:

/* Connection class */
class Connection
{
public:
	Connection();
	virtual ~Connection();

	bool create(Gtk::Window *window, Glib::ustring address, Glib::ustring port);
	bool finish(Gtk::Window *window);
	bool write_message(Gtk::Window *window, Glib::ustring message);

	/* I/O Channel */
	Glib::RefPtr<Glib::IOChannel> c_channel;

protected:
	/* Socket descriptor */
	int c_socket;

	/* Exception error */
	std::auto_ptr<Glib::Error> c_ex;
};

Note that this class has some special methods. They receive Gtk::Window from the application window in order to generate error messages (if any). They also return true if everything went OK and false if an error occurred.

Server application

This section examines the server code related to sockets and I/O operations. Gtk::TextView widget is also explained here. The server application has two sockets and an I/O channel associated for each one. The first socket is the listener for new connections, and the other is activated when a new connection is accepted from a client.

Below is the Server class responsible for dealing with new connections:

/* Server listener class */
class Server
{
public:
	Server();
	virtual ~Server();

	bool create(Gtk::Window *window, int port);
	bool finish(Gtk::Window *window);

	/* Listen socket */
	int s_listen_socket;

	/* Socket address */
	sockaddr_in s_address;

	/* Listen I/O channel */
	Glib::RefPtr<Glib::IOChannel> s_listen_channel;

protected:
	/* Exception error */
	std::auto_ptr<Glib::Error> s_ex;
};

This class contains two special methods:

Now let's see the Connection class which is used when a new connection is accepted by the server. Is also has a special attribute called buffer that is used to store the message read by the read_message method:

/* Client connection class */
class Connection
{
public:
	Connection();
	virtual ~Connection();

	bool create(Gtk::Window *window, Server *server);
	bool finish(Gtk::Window *window);
	bool read_message(Gtk::Window *window);

	/* Message buffer */
	Glib::ustring buffer;

	/* Client Connection I/O channel */
	Glib::RefPtr<Glib::IOChannel> c_conn_channel;

protected:
	/* Client connection socket */
	int c_conn_socket;

	/* Exception error */
	std::auto_ptr<Glib::Error> c_ex;
};

This class contains three special methods:

As you can see, these classes are very similar to each other in some parts, but the creation process differs since each one has a specific purpose. The full source code of this example is available here.

Links