f



To Block or not to Block

Hi,
    I've written a client server application using
non-blocking sockets and most of the time it works fine, apart from
when a message is send down the socket that causes the the
non-blocking socket to want to block. This however returns an error
because it's not able to block.

Therefore is there anyway to get round this problem without setting
the socket to block and not having to send the message in smaller
chunks.

Any advice would be most welcome.

Thanks

Rob
0
robin
7/16/2004 8:47:54 AM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (349) is leader. Post Follow

4 Replies
1139 Views

Similar Articles

[PageSpeed] 46

Robin Cawsey wrote:
> Hi,
>     I've written a client server application using
> non-blocking sockets and most of the time it works fine, apart from
> when a message is send down the socket that causes the the
> non-blocking socket to want to block. This however returns an error
> because it's not able to block.
> 
> Therefore is there anyway to get round this problem without setting
> the socket to block and not having to send the message in smaller
> chunks.

You should really, REALLY consider reorganizing the code structure
to allow sending message in smaller chunks and be able to retry transfer
after socket declared that its buffers are full. It will not necesserely
mean that the sender host will paketize the message differently.

Readings:

1. man poll, man select	- for socket availability monitoring: to send
or receive only when the socket is ready.
2. man setsockopt, section on SO_SNDBUF: to set a larger buffer
which can help you to have better network paketization.
3. man setsockopt, section on SO_SNDLOWAT: to allow select() or
poll() only return when it is known that the socket buffers
can accomodate a certain (.sndbuf - .sndlowat) number of bytes
without blocking.


-- 
Lev Walkin
vlm@lionet.info
0
Lev
7/16/2004 9:05:07 AM
Robin Cawsey <robin.cawsey@btinternet.com> wrote:
>     I've written a client server application using
> non-blocking sockets and most of the time it works fine, apart from
> when a message is send down the socket that causes the the
> non-blocking socket to want to block. This however returns an error
> because it's not able to block.

Do you mean that there is a special type of message for which would
like to block or does that mean that you want to block whenever you
for some reasons you don't tell a message is supposed to arrive?

> Therefore is there anyway to get round this problem without setting
> the socket to block and not having to send the message in smaller
> chunks.

This looks a bit as if you're looking for select(2). Keep the socket
in blocking mode, but instead of trying to read on it immediately
call select() before you do so. Since you can tell select() to wait
either infinitely long, for a certain amount of time or not at all
and it tells you if a read on the socket file descriptor would block
or not I would guess that that's what you need. Don't get thrown
off by the man page being not one of the shortest ones;-)

                                    Regards, Jens
-- 
  \   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
   \__________________________  http://www.toerring.de
0
Jens
7/16/2004 9:09:29 AM
Lev Walkin wrote:

> Robin Cawsey wrote:

>>     I've written a client server application using
>> non-blocking sockets and most of the time it works fine, apart from
>> when a message is send down the socket that causes the the
>> non-blocking socket to want to block. This however returns an error
>> because it's not able to block.

    Right, that's exactly what's supposed to happen.

>> Therefore is there anyway to get round this problem without setting
>> the socket to block and not having to send the message in smaller
>> chunks.

    Err, what problem? You don't have to set the socket to block or send the 
message in smaller chunks. Use 'poll' or 'select'. How were you deciding 
when to 'read' the socket anyway?

> 1. man poll, man select - for socket availability monitoring: to send
> or receive only when the socket is ready.

    Definitely.

> 2. man setsockopt, section on SO_SNDBUF: to set a larger buffer
> which can help you to have better network paketization.
> 3. man setsockopt, section on SO_SNDLOWAT: to allow select() or
> poll() only return when it is known that the socket buffers
> can accomodate a certain (.sndbuf - .sndlowat) number of bytes
> without blocking.

    I don't recommend messing with either of these. Enlarging the send 
buffer won't buy you anything because the default send buffer is large 
enough to get proper packetization on anything but the fastest, lowest 
latency links. Messing with SO_SNDLOWAT is dangerous too.

    DS


0
David
7/16/2004 11:39:21 AM
On Fri, 16 Jul 2004 01:47:54 -0700, Robin Cawsey wrote:

> Hi,
>     I've written a client server application using
> non-blocking sockets and most of the time it works fine, apart from
> when a message is send down the socket that causes the the
> non-blocking socket to want to block. This however returns an error
> because it's not able to block.
>
> Therefore is there anyway to get round this problem without setting
> the socket to block and not having to send the message in smaller
> chunks.

 A blocking IO design should look roughly like...

 char **bufs = ...;
 while_foo()
   gather_data_from_socket(fd, bufs[fd]);
   if_enough_data(bufs[fd])
      work_on_data(bufs[fd]);

....where as a blocking IO design tends to look more like...

 char *buf = ...;
 while_foo()
   gather_data_from_socket(fd, buf);
   work_on_data(buf);

....it sounds like you are trying to do the blocking IO design, but
using non-blocking IO. This obviously doesn't work well.

 You might want to look at: http://www.and.org/texts/network_io.html

-- 
James Antill -- james@and.org
Need an efficient and powerful string library for C?
http://www.and.org/vstr/

0
James
7/16/2004 8:19:14 PM
Reply: