On Tue, 7 Dec 2004, Sven Neumann wrote:
Hi,
Scott Dattalo <scott@xxxxxxxxxxx> 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 _______________________________________________ gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list