Re: g_io_channel_read_chars vs.g_io_channel_read



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]