Sockets & IO Channels
- From: Henri Häkkinen <henri hakkinen pp2 inet fi>
- To: gtk-app-devel-list gnome org
- Subject: Sockets & IO Channels
- Date: Mon, 21 Jul 2008 15:23:48 +0300
Hello,
I am trying to create a GTK+ application that would connect to a TELNET
server and all data received from it would be outputted to a GtkTextView
widget in a GtkWindow. The window also has a GtkEntry widget that allows
the user to enter text, which in turn is sent to the server.
I am using GLib IO Channels for the socket input/output. Here is a
sample code from my application:
-----------------------
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netdb.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
/* user interface */
GtkWindow *terminal = NULL;
GtkTextView *buffer = NULL;
GtkEntry *input = NULL;
/* event handlers */
void
on_input_activate (GtkEntry *entry, gpointer user_data)
{
const gchar *text;
g_assert (entry != NULL);
text = gtk_entry_get_text (entry);
g_debug ("Input: %s", text);
/* TODO: sent the text to the server */
gtk_entry_set_text (entry, "");
}
static GIOChannel *
open_socket_channel (const char *hostname, int port)
{
struct hostent *h;
struct sockaddr_in a;
int fd;
g_assert (hostname != NULL);
g_assert (port > 0);
h = gethostbyname2 (hostname, AF_INET);
g_assert (h != NULL);
a.sin_family = AF_INET;
a.sin_port = htons (port);
a.sin_addr.s_addr = *((uint32_t *) h->h_addr);
g_debug ("%s - %d.%d.%d.%d", hostname,
(a.sin_addr.s_addr & 0x000000ff),
(a.sin_addr.s_addr & 0x0000ff00) >> 8,
(a.sin_addr.s_addr & 0x00ff0000) >> 16,
(a.sin_addr.s_addr & 0xff000000) >> 24);
fd = socket (PF_INET, SOCK_STREAM, 0);
g_assert (fd != -1);
if (connect (fd, (struct sockaddr *) &a, sizeof (a)) == -1)
{
/* TODO: error handling */
}
return g_io_channel_unix_new (fd);
}
static gboolean
readfunc (GIOChannel *channel, GIOCondition condition, gpointer data)
{
gchar *str;
gsize length;
g_assert (channel != NULL);
g_assert (buffer != NULL);
g_io_channel_read_to_end (channel, &str, &length, NULL);
/* TODO: output the string to the window */
g_free (str);
return TRUE;
}
int
main (int argc, char **argv)
{
GladeXML *xml;
GIOChannel *channel;
gtk_init (&argc, &argv);
/* Load the user interface. */
xml = glade_xml_new ("foo.glade", NULL, NULL);
if (!xml)
return 0;
glade_xml_signal_autoconnect (xml);
terminal = GTK_WINDOW (glade_xml_get_widget (xml, "terminal"));
buffer = GTK_TEXT_VIEW (glade_xml_get_widget (xml, "buffer"));
input = GTK_ENTRY (glade_xml_get_widget (xml, "input"));
g_assert (terminal != NULL);
g_assert (buffer != NULL);
g_assert (input != NULL);
/* Open connection to the server. */
channel = open_socket_channel ("foo.org", 23);
g_assert (channel != NULL);
g_io_channel_set_encoding (channel, NULL, NULL);
g_io_channel_set_close_on_unref (channel, TRUE);
g_io_add_watch (channel, G_IO_IN, readfunc, NULL);
/* Show the main window and run main loop. */
gtk_widget_show_all (GTK_WIDGET (terminal));
gtk_main ();
return 0;
}
------------------------
This however, seems not to be working for some reason. The application
window shows up, but it hangs (not responding to any events). Do I need
to set my socket into non-blocking mode? Is the IO Channels the best way
to handle the socket I/O or is there a better way to do this? Are there
any problems with this method? Any comments or ideas?
- Henri H.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]