Re: g_io_channel_read_chars vs.g_io_channel_read
- From: Scott Dattalo <scott dattalo com>
- To: gtk-list gnome org
- Subject: Re: g_io_channel_read_chars vs.g_io_channel_read
- Date: Tue, 7 Dec 2004 15:09:26 -0800 (PST)
On Tue, 7 Dec 2004, Sven Neumann wrote:
Hi,
Scott Dattalo <scott dattalo com> writes:
g_io_channel_read_chars() is the designated replacement for the
deprecated g_io_channel_read(). However, the two functions behave
differently
IIRC they behave identically if you set the io-channel encoding to
NULL and disable buffering.
Hi Sven,
Before addressing your suggestion, you can page down and see how I got 
this g_io_channel_read_chars() to not block. But if you want to read the 
whole mystery novel...
By setting the encoding to NULL and disabling buffering, do you mean 
this?:
    GError *err = NULL;
    GIOStatus stat;
    stat = g_io_channel_set_encoding (channel, NULL, &err);
    stat = g_io_channel_set_flags (channel, G_IO_FLAG_SET_MASK, &err);
If so, I found that this *still* blocks. I've also tried replacing 
G_IO_FLAG_SET_MASK with G_IO_FLAG_NONBLOCK and the behavior was no 
different. The reason I tried this is because I saw a similar suggestion 
you made in the archives.
I make these calls immediately after the socket has been created:
Stripping out the error checking, this is essentially what's left for 
socket creation:
  struct   sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int new_socket;
  int on = 1;
  new_socket = socket(AF_INET, SOCK_STREAM, 0);
  setsockopt ( new_socket, SOL_SOCKET, SO_REUSEADDR, ( const char* ) 
&on, sizeof ( on ) );
  memset (&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_port = htons(PORT);
  bind (new_socket, (struct sockaddr *) &addr, sizeof(addr));
  listen (new_socket, 5);
At this point, I create an io_channel to watch for client connections. 
When a client attempts to connect() to my server, the callback is called. 
Then, in that callback I do something like:
  client_socket = accept (new_socket,(struct sockaddr *)  &addr, 
&addrlen);
followed by code that creates another io_channel for receiving data from 
the client.
Now, here's one more interesting observation. The one-byte-read poll loop 
Tristan suggests does not work. However, this snippet of code:
    do {
      GIOStatus stat = g_io_channel_read_chars(channel, buffer, 1, 
&bytes_read, &err);
      printf("read: %c  ", *buffer);
      debugPrintChannelStatus(stat);
      debugPrintCondition(g_io_channel_get_buffer_condition (channel));
    } while(bytes_read);
Will read a byte at a time and will block after all of the bytes have been 
read. But what's interesting, the block occurs in the call to 
g_io_channel_get_buffer_condition and *NOT* in g_io_channel_read_chars. 
Hmmm...
So then I decided to try setting the channel non blocking flag in the 
channel call back function. When I did this I discovered that the last 
GIOStatus returned was G_IO_STATUS_AGAIN - which means the resource is not 
available. So then I tried this:
    bytes_read = 0;
    do {
      unsigned int b;
      stat = g_io_channel_read_chars(channel, &s->buffer[bytes_read], 1, 
&b, &err);
      bytes_read++;
      printf("read: %c  ", *s->buffer);
      debugPrintChannelStatus(stat);
      debugPrintCondition(g_io_channel_get_buffer_condition (channel));
    } while(G_IO_STATUS_NORMAL == stat);
And finally, this works. Well, works is too strong - it functions properly 
but looks damned suspicious.
Scott
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]