Problem with non-blocking writing using sockets

Problem with non-blocking writing using sockets

Post by Andreas Gie » Tue, 26 Jan 1999 04:00:00



I try to build up a program structure consisting of a couple of client
processes, which
communicate to each other using sockets. The communication is managed by
a server
process. The programs are written in C based on a LINUX-platform. (I
hope You UNIX
programmers are also able to give me a hint.)

My problem:
When sending a long message to another program (should be up to 1 MByte)
I first
check weather the connection line is able to receive data (SELECT).
Then the WRITE statement transmits the first portion to the socket
buffer and
waits until the target program reads the data from the buffer.
If the target program is busy that moment, the sending program is
blocked.

so my question:
Is it possible to find out the size of the socket buffer (which differs
from one WRITE
to the other) and the remaining space in the buffer ?
(so I can write only the exact number of bytes without WRITE-blocking)

thanx a lot

 
 
 

Problem with non-blocking writing using sockets

Post by jhal.. » Tue, 26 Jan 1999 04:00:00




Quote:>When sending a long message to another program (should be up to 1 MByte)
>I first
>check weather the connection line is able to receive data (SELECT).
>Then the WRITE statement transmits the first portion to the socket
>buffer and
>waits until the target program reads the data from the buffer.
>If the target program is busy that moment, the sending program is
>blocked.

>so my question:
>Is it possible to find out the size of the socket buffer (which differs
>from one WRITE
>to the other) and the remaining space in the buffer ?
>(so I can write only the exact number of bytes without WRITE-blocking)

There's no way to get the number of bytes that can be sent at any
given time, you'll need to keep track of where you are, and send only
once when select() says you won't block. For example:

struct IONode
{
  char   *buf;
  int     msgSize;
  int     ioCount;
  struct IONode *next;

Quote:};

When you want to send the buffer, point to it with the buf member, and
initialize msgSize to the number of bytes to be sent and ioCount to 0.

When select() says the descriptor is ready to write, tell write() to
send it all. It probably won't send it all, but it will tell you how
much it did send.

Add the number of bytes it sent to ioCount, and subtract it from
msgSize.

Next time select() says you can write(), tell it to send msgSize bytes
starting at (buf + ioCount), and adjust msgSize and ioCount again by
how many bytes were sent. Keep doing that till the buffer's been
sent.

Joe

 
 
 

Problem with non-blocking writing using sockets

Post by Rainer Temm » Tue, 26 Jan 1999 04:00:00



> My problem:
> When sending a long message to another program (should be up to 1 MByte)
> I first
> check weather the connection line is able to receive data (SELECT).
> Then the WRITE statement transmits the first portion to the socket
> buffer and
> waits until the target program reads the data from the buffer.
> If the target program is busy that moment, the sending program is
> blocked.

> so my question:
> Is it possible to find out the size of the socket buffer (which differs
> from one WRITE
> to the other) and the remaining space in the buffer ?
> (so I can write only the exact number of bytes without WRITE-blocking)

You can't find out the bufferspace which is available for a write(), but what
you can do is to set the socket to nonblocking mode.

This will change the behaviour of the write() call. In nonblocking mode
write() will return the number of bytes that has been written (instead of
blocking until all bytes are written).

If you use select() or poll() to check if the socket is writeable before
calling write() you should be able to handle the situation without
blocking your program at any point.

Regards Rainer

 
 
 

Problem with non-blocking writing using sockets

Post by Andreas Gie » Tue, 26 Jan 1999 04:00:00




> > My problem:
> > When sending a long message to another program (should be up to 1 MByte)
> > I first
> > check weather the connection line is able to receive data (SELECT).
> > Then the WRITE statement transmits the first portion to the socket
> > buffer and
> > waits until the target program reads the data from the buffer.
> > If the target program is busy that moment, the sending program is
> > blocked.

> > so my question:
> > Is it possible to find out the size of the socket buffer (which differs
> > from one WRITE
> > to the other) and the remaining space in the buffer ?
> > (so I can write only the exact number of bytes without WRITE-blocking)

> You can't find out the bufferspace which is available for a write(), but what
> you can do is to set the socket to nonblocking mode.

> This will change the behaviour of the write() call. In nonblocking mode
> write() will return the number of bytes that has been written (instead of
> blocking until all bytes are written).

> If you use select() or poll() to check if the socket is writeable before
> calling write() you should be able to handle the situation without
> blocking your program at any point.

> Regards Rainer

I'm glad about your hint, and now I only have to know, how the socket
can be set to non-blocking mode.

Andreas

 
 
 

Problem with non-blocking writing using sockets

Post by jhal.. » Tue, 26 Jan 1999 04:00:00






>> This will change the behaviour of the write() call. In nonblocking mode
>> write() will return the number of bytes that has been written (instead of
>> blocking until all bytes are written).

>> If you use select() or poll() to check if the socket is writeable before
>> calling write() you should be able to handle the situation without
>> blocking your program at any point.

>> Regards Rainer

>I'm glad about your hint, and now I only have to know, how the socket
>can be set to non-blocking mode.

The description above of how write() works is a little misleading. You
always get back the number of bytes written, or -1, when you call
write(), whether the descriptor is in non-blocking mode or not. Also,
write doesn't block "until all bytes are written" in either mode. In
blocking mode it blocks until it can write at least one byte, then it
returns how many it wrote.

If you only call write() once when select() tells you the socket is
ready, you won't block, and write() will tell you how many bytes were
written. There's no point in trying to write() more than once at a
time, because write() will send as many bytes as it can the first time
(assuming you always tell it to send all remaining bytes).

It isn't non-blocking mode that's the answer (although there's nothing
wrong with doing that), select() is the answer. Whether you use
non-blocking mode or not, you wind up doing the same thing.

Joe

 
 
 

Problem with non-blocking writing using sockets

Post by Rainer Temm » Tue, 26 Jan 1999 04:00:00



> I'm glad about your hint, and now I only have to know, how the socket
> can be set to non-blocking mode.

see man-pages for fcntl() cmd's O_NONBLOCK and O_NDELAY,
...
there is a slight difference between them (which i don't know right now,
i have to admit)
but generally both can be used to change from blocking to nonblocking
mode.
Hint: If you change to nonblocking mode before calling connect()
the connect is done without blocking your program too.

Regards Rainer

 
 
 

1. TCP Socket Non-Blocking write ?

Is there a way to determine if a TCP stream socket has enough buffer
space to complete a non-blocking write of an entire buffer with a single
write call without actually performing the write ?

The socket is set to "NO DELAY", and I want to avoid a partial write.
This program is running on a Sun Sparc-station, SunOS 4.1.1.

Please email responses directly to me if possible.

---------------------------------------------------------------------------
---------------------------------------------------------------------------

2. PPTP Multicast?

3. non-blocking writes to sockets

4. Call to support `umount -f' in the KERNEL! (Re: NFS umount???)

5. TCP Socket Non-Blocking write ?

6. digitiser tablets - recommendations?

7. Wanted: non-blocking socket write...

8. a JAVA mini DHCP server

9. Does non-blocking (sockets) apply to write?

10. [2.5] Non-blocking write can block

11. Using select() on non-blocking socket?

12. EACCES error when using POSIX Threads and non-blocking sockets

13. Blocking and Non-Blocking socket