Non blocking socket blocks; says 'read would block' ?

Non blocking socket blocks; says 'read would block' ?

Post by Atiqullah Hash » Sat, 02 May 1992 06:38:16



Hi all,

I have three sockets in server which I am reading in a continuous loop,
so don't want to wait on any one. I have designated them as 'non blocking'
but when run the server exits on the very first read() and says 'would
block'. (Is it the same as 'EWOULDBLOCK' mentioned in R. Steven's book ?)
I don't want that I should get any error msg and exit, in fact the
whole purpose of nonblocking is that if something is available, read it
else proceed in the loop and come back to read next time.
The client (sender) is sending msgs on all three sockets. The sockets
are conn_oriented. I am using SunOS 4.1. The small code part is below:

int emer_s, env_s, sens_s;            /* socket fds */
//----------- making sockets nonblocking ******
if ((res=fcntl(emer_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }
if ((res=fcntl(env_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }
if ((res=fcntl(sens_s,F_SETFL,FNDELAY)) < 0)
        {
          perror("fcntl res = -1");
          exit(1);
        }

for(; ;)
   {

      if ((cc=read(emer_s,(char*)&gen_struct,size)) < size)
        {
        perror("read error");
          exit(1);
        }
......... do something
      if ((cc=read(env_s,(char*)&gen_struct,size)) < size)
        {
         perror("read error");
          exit(1);
        }
        ......... do something
      if ((cc=read(sens_s,(char*)&gen_struct,size)) < size)
        {
          perror("read error");
          exit(1);
        }
        ......... do something

   }

Any help is appreciated.

hashmi

--
-----
Atiqullah Hashmi                    
UTA (Univ. of Texas at Arlington)  

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Jonathan I. Kame » Sun, 03 May 1992 03:04:36


Yes, the error you are getting is EWOULDBLOCK, and the Stevens book
almost certainly makes clear how to check for that (I don't have a
copy of the book with me, but I can't verify that for sure, but I
suspect you didn't read carefully enough).  If you have a non-blocking
socket and read() returns an error, then you should check to see if
errno == EWOULDBLOCK, and if so, ignore the error.

Something like changing your if statements that do the read()s to
this:

      if ((cc=read(emer_s,(char*)&gen_struct,size)) < size)
        {
        if (errno == EWOULDBLOCK)
          {
          cc = 0;
          }
        else
          {
          perror("read error");
            exit(1);
          }
        }

Make sure you have declared "extern int errno;".

Another thing I notice is that if you're trying to read in succesion
from multiple sockets like that, you're almost certainly better off
using select(), in order to prevent busy-waiting when no input is
available.  This avoids the EWOULDBLOCK, too.

--

MIT Information Systems/Athena              Moderator, news.answers
    (Send correspondence related to the news.answers newsgroup
        {and ONLY correspondence related to the newsgroup}


 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Shikhar Baj » Sun, 03 May 1992 04:47:33


Quote:>Hi all,

>I have three sockets in server which I am reading in a continuous loop,
>so don't want to wait on any one. I have designated them as 'non blocking'
>but when run the server exits on the very first read() and says 'would
>block'. (Is it the same as 'EWOULDBLOCK' mentioned in R. Steven's >book ?)

It sure is.

Quote:>I don't want that I should get any error msg and exit, in fact the
>whole purpose of nonblocking is that if something is available, read it
>else proceed in the loop and come back to read next time.
>The client (sender) is sending msgs on all three sockets. The sockets
>are conn_oriented. I am using SunOS 4.1. The small code part is below:

>int emer_s, env_s, sens_s;            /* socket fds */
>//----------- making sockets nonblocking ******
>if ((res=fcntl(emer_s,F_SETFL,FNDELAY)) < 0)
>    {
>      perror("fcntl res = -1");
>      exit(1);
>    }
>if ((res=fcntl(env_s,F_SETFL,FNDELAY)) < 0)
>    {
>      perror("fcntl res = -1");
>      exit(1);
>    }
>if ((res=fcntl(sens_s,F_SETFL,FNDELAY)) < 0)
>    {
>      perror("fcntl res = -1");
>      exit(1);
>    }

>for(; ;)
 >  {

>   if ((cc=read(emer_s,(char*)&gen_struct,size)) < size)
>    {
>        perror("read error");
>      exit(1);
>    }

Stop right there.  Your problem is in  the read.   First of all, if you
have fewer
that 'size' bytes (but more than 0) in the receive buffer  during the
read, you will go into the decision.

For the case where the buffer is empty, the read() will return -1 and
errno will be set to EWOULDBLOCK.  So once again, you would go
into the decision.

Therefore, your if-then clause should look like

     if (((cc=read(env_s,(char*)&gen_struct,size)) <  0)
        && (errno != EWOULDBLOCK))
        {
         perror("read error");
          exit(1);
        }

Of course, you should include <sys/errno.h> somewhere.   Note that I check
if the read returns less than 0 instead of less than 'size'.  I'm assuming that
you don't care how many characters you get during the read() as long
as you get something.  Cheers.

Shikhar Bajaj
Bell Communications Research
445 South Street
Morristown, NJ 07962-1910
MRE 2Q-178
(201) 829-4541

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Jeff L » Mon, 11 May 1992 16:10:55



>>//----------- making sockets nonblocking ******
>>if ((res=fcntl(emer_s,F_SETFL,FNDELAY)) < 0)
>>        perror("read error");

>>  ...........  <stuff deleted> ............

>Stop right there.  Your problem is in  the read.   First of all, if you
>have fewer
>that 'size' bytes (but more than 0) in the receive buffer  during the
>read, you will go into the decision.

>For the case where the buffer is empty, the read() will return -1 and
>errno will be set to EWOULDBLOCK.  So once again, you would go
>into the decision.

>Therefore, your if-then clause should look like

>     if (((cc=read(env_s,(char*)&gen_struct,size)) <  0)
>    && (errno != EWOULDBLOCK))
>    {

> .............   <stuff deleted> .........

>Shikhar Bajaj
>Bell Communications Research
>445 South Street
>Morristown, NJ 07962-1910
>MRE 2Q-178
>(201) 829-4541


Shikhar's points are correct, except that since you are using
SUNOS 4.1.1, instaed of read() returning  -1 on a non-blocking
socket for EWOULDBLOCK, it will return 0.

--
   Jeff Lin                                        |/                

   6464 Savoy Dr.       Phone:    713-975-4592    /|                  
   Houston, TX 77036     ________________________/ | ______________  

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Guy Harr » Tue, 12 May 1992 09:48:07


Quote:>Shikhar's points are correct, except that since you are using
>SUNOS 4.1.1, instaed of read() returning  -1 on a non-blocking
>socket for EWOULDBLOCK, it will return 0.

Only if you turn S5-style non-blocking I/O on.  If you turn BSD-style
non-blocking I/O on, it returns -1 and sets "errno" to EWOULDBLOCK; if
you turn POSIX-style non-blocking I/O on, it returns -1 and sets "errno"
to EAGAIN.

(And it's "SunOS", not "SUNOS".)

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Shikhar Baja » Wed, 13 May 1992 00:57:26


Quote:Jeff Lin writes:
>Shikhar's points are correct, except that since you are using
>SUNOS 4.1.1, instaed of read() returning  -1 on a non-blocking
>socket for EWOULDBLOCK, it will return 0.

So says the man pages for read(2v) under 4.1.2:
-----
When attempting to read from a descriptor associated with an empty
pipe, socket, FIFO, or stream:

- If  the object the descriptor is associated with is marked for 4.2 BSD-style
    non-blocking I/O (with the FIONBIO ioctl() requestor a call to fcntl(2V)
    using the FNDELAY flag from <sys/file.h> or the O_NDELAY flag from
    <fcntl.h> in the 4.2 BSD enivronment), the read will return -1 and errno
    will be set to EWOUDBLOCK.
-------

If System V-style non-blocking I/O is used, the man pages says that then
zero will be returned.

Shikhar Bajaj
Bell Communications Research
445 South Street
Morristown, NJ 07962-1910
MRE 2Q-178
(201) 829-4541

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Tay Beng Ha » Tue, 12 May 1992 21:17:13



    >Only if you turn S5-style non-blocking I/O on.  If you turn BSD-style

        How can we know S5-style or BSD-style non-blokcing I/O is turned on?
        Also, how to turn either one (BSD or S5) non-blocking I/O on? (use
        fcntl() or ioctl() ?)

    >non-blocking I/O on, it returns -1 and sets "errno" to EWOULDBLOCK; if
    >you turn POSIX-style non-blocking I/O on, it returns -1 and sets "errno"
    >to EAGAIN.

        Thanks.

Best regards,
 ____________________________________________________________________________
| Beng-Hang Tay                       | Telnet:    520 8732                  |
| Singapore Networks Operation        | Phone:     (65) 279 8732             |
| Hewlett-Packard Singapore Pte. Ltd. | Fax:       (65) 272 2780             |


| Republic of Singapore               |                                      |
 ----------------------------------------------------------------------------

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Guy Harr » Wed, 13 May 1992 10:30:14


Quote:>    How can we know S5-style or BSD-style non-blokcing I/O is turned on?

Well, either:

1) you used "fcntl()" to turn it on, in which case, either:

        1) you turn O_NDELAY on - if so, then:

                if your program was compiled in the BSD environment, i.e.
                with "/usr/bin/cc" (and no funny tricks to change which
                environment's include files and libraries you got), it's
                turning BSD-style non-blocking I/O on;

                if your program was compiled in the S5 environment, i.e.
                with "/usr/5bin/cc" (and no funny tricks to change which
                environment's include files and libraries you got), it's
                turning S5-style non-blocking I/O on.

        2) you turn FNDELAY or _FNDELAY on - if so, then it's turning
           BSD-style non-blocking I/O on.

        3) you turn FNBIO or _FNBIO on - if so, then it's turning
           S5-style non-blocking I/O on.

2) you used "ioctl()" to turn it on, in which case it's turning
   BSD-style non-blocking I/O on.

If you use O_NONBLOCK, you get POSIX-style non-blocking I/O, not
surprisingly.

Quote:>    Also, how to turn either one (BSD or S5) non-blocking I/O on? (use
>    fcntl() or ioctl() ?)

See above.
 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Mark William Hopki » Sun, 17 May 1992 07:54:20



Quote:>Make sure you have declared "extern int errno;".

>Another thing I notice is that if you're trying to read in succesion
>from multiple sockets like that, you're almost certainly better off
>using select(), in order to prevent busy-waiting when no input is
>available.  This avoids the EWOULDBLOCK, too.

Based on certain quirks that I've observed in a certain widely implemented
networking program, I believe that there is a bug in most implementations of
select() that will cause blocking I/O to still be able to get through.

Keep the sockets non-blocking EVEN WITH SELECT() and use EWOULDBLOCK to check
for blocks.

A better alternative is to avoid select() entirely and set up a input
processing loop for each input device, and use whatever multi-programming
facilities your machine has (i.e. fork(), semaphores, shared memory, message
passing) to get these loops to run concurrently.

The code is far cleaner and modular.  You don't have to tear everything apart
and thread it all by hand into one huge polling or select() loop, and most
of all, you don't need select() anymore.

This, for instance is an outline for a simple client communications program
(derived from something actually in use).  The device I/O consists of nothing
more than single calls to read() and write().  Multitasking means you don't
need to ever worry about blocking: each process is running independently of
the others.

(This method implies the use of either semaphores or windowing to ensure
mutual exclusion on the TTY output device and semaphores for all other
non-sharable output devices).

main() {
   int Client, PS ...
   <Make Client, connect to given Host and Port>
   PS = fork();
   if (PS != 0) { /* TTY loop */
      while (1) {
         char Buf[0x100]...
         <Get line of input from TTY into Buf>
         if EOF encountered:
            close(Client), kill(PS, 9), exit(0);
         <Send line through Client socket>
      }
   } else { /* Socket loop */
      while (1) {
         char Buf[0x100] ...
         <Read packet from Client socket>
         <Interpret and display packet>
      }
   }

Quote:}

 
 
 

Non blocking socket blocks; says 'read would block' ?

Post by Jim Robins » Thu, 21 May 1992 02:31:15


Quote:>>Shikhar's points are correct, except that since you are using
>>SUNOS 4.1.1, instaed of read() returning  -1 on a non-blocking
>>socket for EWOULDBLOCK, it will return 0.

>Only if you turn S5-style non-blocking I/O on.  If you turn BSD-style
>non-blocking I/O on, it returns -1 and sets "errno" to EWOULDBLOCK; if
>you turn POSIX-style non-blocking I/O on, it returns -1 and sets "errno"
>to EAGAIN.

Why did Sun (in SunOS 4.1.1) not apply to sockets the semantics of
POSIX-style non-blocking writes associated with pipes (& FIFOs)? I.e. a
write of n bytes to a pipe/FIFO which has been marked for non-blocking
POSIX-style I/O will either completely succeed and return n, or will return
-1 with errno set to EAGAIN; partial writes will not occur. Yet, on a TCP
socket (and using the /usr/5lib/libc.a or the "normal" libc), it is
possible to get a partial write if the socket cannot hold the entire amount
that is attempting to be written.  It seems to me that it would make sense
to treat a stream socket in the same manner as a pipe/FIFO wrt non-blocking
writes and use the relevant semantics; as it is now, Sun seems to have only
partially implemented POSIX-style non-blocking I/O on stream sockets. The
ability to write all or nothing is a very useful feature and I cannot
understand why Sun would not go the small extra distance and implement full
POSIX non-blocking semantics on stream sockets.
--
Jim Robinson

{ubc-cs!van-bc,uunet}!mdivax1!robinson
 
 
 

1. Non-blocking socket reads block! (Bug?)

Boy, I hope this hasn't been addressed already...  

I have an application which builds and runs correctly under a wide variety
of Unicies (ULTRIX, AIX, SUN, NeXT, etc.)  It is a daemon which listens
on a port, and does things when a client connects to it (TCP socket streams).

The main body of the daemon is a tight loop which does read(2) on a socket
descriptor returned earlier by an accept(2).  As you might suspect, the
socket ought to be non-blocking, so that work can continue if there is no
data waiting to be processed, and so it is.  After the call to socket(2),
I do a fcntl(2) on the descriptor setting the O_NDELAY flag (that's
O_NONBLOCK to you POSIX types...)  This correctly makes the socket and
subsequent calls to read(2) non-blocking on all other platforms.  But
the read() blocks under Linux (1.2.9 kernel).

I was able to fix the problem by also doing a fcntl() on the socket descriptor
returned by accept() and setting the O_NDELAY flag there too (it has to be
set on _both_; just setting it on the one returned by accept makes the
read() block).  Weird.  I read the man pages again, and I saw nothing to
indicate that it didn't have to be done that way...  but, as I said, this
code worked fine on tons of other platforms.

So, am I on drugs?  Is this a known bug?  An unknown bug?  Any help would
be appreciated (though, as I said, the code now works -- I'm just curious
as to what the deal is...)

Thanks!

--
 ============================================================================
|    Peter (Z-Man) Zatloukal   |  That is not dead, which may forever lie,   |

 ============================================================================

2. 2 IP on the same ethernet card on RedHat 4.1

3. Non-Block read & Block read

4. Unused accounts

5. drivers/block/block.o: In function `rd_blkdev_pagecache_IO' and `rd_make_request': undefined reference to `bio_size'

6. ip_queue

7. Non-Block socket read can't detect a broken link after resetting the system

8. Ximian Evolution on Solaris 9

9. Blocking and Non-Blocking socket

10. Difference between blocking and non-blocking socket ?

11. changing socket to blocking after non blocking connect

12. What is difference of SYNC, ASYNC, BLOCKING, NON-BLOCKING sockets?

13. Non-blocking sockets on SunOS 4 are blocking