How to coordinate/control write()s to a socket?

How to coordinate/control write()s to a socket?

Post by simon gola » Wed, 03 Jul 1996 04:00:00



Hi,

I need to analyze a potrential situation and possibly change the strategy
of our application. Here is the critical part of the application which has
to do with sockets (SunOS, TCP sockets, C language and gcc complier).

When a certain test starts, a Supplier starts generating packets and writing
them to a socket. This is done in a loop, where on each iteration a packet is
written (and other, non-related things happen as well). Another part of
the system, a Consumer, reads these packets as they arrive on the socket.
This is done in a totally asyncronous mode, till the end of the test. The
problem is that sometimes the Consumer consumes the packets in a slower pace
than the Supplier generates them. Therefore there is a need to add some
"smart" logic to the Supplier, so that it will be able to detect when there
are packets still waiting to be consumed, and not generate a packet at such
time.

I did not find (or just missed) any ideas in Stevens books, or FAQ.

One direction I have at the moment is to change the write() of the
Supplier to something like (in pseudo-code):

while( not-finished-writing-whole-packet )
{
  n = write(osock, packet, size);
  if( n == size )
    finished-writing-whole-packet;
  else
  {
    decrease size by value of n;
    advance some pointer on packet;
  }

Quote:}

However, this is just temporary and is probably not sufficient, because
now the Supplier does not take care of other events in its main loop and is
really busy with the Consumer (and depends on its speed). What I would really
like to have in the main loop of the Supplier is:

while( run-forever-in-this-main-loop )
{
  if( no-packets-pending-on-socket ||
      just-a-few-packets-pending-on-socket ||
      enough-space-on-the-socket-to-write-another-packet )
    generate-and-write-another-packet;

  /* continue with other events and things to do */
  ...

Quote:}

I would appreciate any ideas/pointers/suggestions.

--

\_\_\_  Without action there is no change. _/_/_/

 
 
 

How to coordinate/control write()s to a socket?

Post by Sami Tik » Mon, 08 Jul 1996 04:00:00



>When a certain test starts, a Supplier starts generating packets and writing
>them to a socket. This is done in a loop, where on each iteration a packet is
>written (and other, non-related things happen as well). Another part of
>the system, a Consumer, reads these packets as they arrive on the socket.
>This is done in a totally asyncronous mode, till the end of the test. The
>problem is that sometimes the Consumer consumes the packets in a slower pace
>than the Supplier generates them. Therefore there is a need to add some
>"smart" logic to the Supplier, so that it will be able to detect when there
>are packets still waiting to be consumed, and not generate a packet at such
>time.

Isn't this the case for non-blocking sockets and select()?

When a write to a non-blocking socket returns EWOULDBLOCK, remember
the pointer into the packet you were writing, add the socket to a
select write-set and enter select().

Select will return when the socket has become writable. In select you
can also watch for other events to happen or have a timeout.

Sami

 
 
 

How to coordinate/control write()s to a socket?

Post by Jeff Dickso » Fri, 12 Jul 1996 04:00:00




>>When a certain test starts, a Supplier starts generating packets and writing
>>them to a socket. This is done in a loop, where on each iteration a packet is
>>written (and other, non-related things happen as well). Another part of
>>the system, a Consumer, reads these packets as they arrive on the socket.
>>This is done in a totally asyncronous mode, till the end of the test. The
>>problem is that sometimes the Consumer consumes the packets in a slower pace
>>than the Supplier generates them. Therefore there is a need to add some
>>"smart" logic to the Supplier, so that it will be able to detect when there
>>are packets still waiting to be consumed, and not generate a packet at such
>>time.

>Isn't this the case for non-blocking sockets and select()?

>When a write to a non-blocking socket returns EWOULDBLOCK, remember
>the pointer into the packet you were writing, add the socket to a
>select write-set and enter select().

>Select will return when the socket has become writable. In select you
>can also watch for other events to happen or have a timeout.

>Sami

I don't believe non blocking writes are conclusive. There is not a one to one
correspondance between what's written and read. The socket will always be
writable provided that the connection remains open and adequate buffer space is
available. How about sending some kind of go ahead message to the sender when
all data received upto that point had been consumed (synchronization).

Jeff

 
 
 

How to coordinate/control write()s to a socket?

Post by Vincent Giacomin » Thu, 28 Nov 1996 04:00:00



> Hi,

> What I would really
> like to have in the main loop of the Supplier is:

> while( run-forever-in-this-main-loop )
> {
>   if( no-packets-pending-on-socket ||
>       just-a-few-packets-pending-on-socket ||
>       enough-space-on-the-socket-to-write-another-packet )
>     generate-and-write-another-packet;

>   /* continue with other events and things to do */
>   ...
> }

> I would appreciate any ideas/pointers/suggestions.

> --

> \_\_\_  Without action there is no change. _/_/_/

Try to use function select (see man page)

the solution to your problem would be like this:

#include <sys/types.h>

struct fd_set           write ;
struct timeval          TO = { 0,10 }  /* 10 us */

FD_ZERO(&write)
FD_SET(osock,&write)
try_again:
switch(select(osock+1,NULL,&write,NULL,&TO))
{
  case -1 : if (errno != EINTR) /* Ouch ! */
            else goto try_again ;
  case 0  : /* time out: 10 us */
            /* do something else */
            break ;
  default : /* avaibality to write on socket ? */
            if (FD_ISSET(osock,&write)
            {
                /* write socket */
            }

Quote:}

Hope this helps...
--
Vincent GIACOMINI
STERIA SUD OUEST
271, avenue de Grande Bretagne
Immeuble "Le Phnicia", BP3111
31026 TOULOUSE Cedex
Tel #  : (33) 05 62 12 20 61
fax #  : (33) 05 61 31 07 02