Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

How do I do a non-blocking accept?

by Anonymous Monk
on Mar 30, 2000 at 19:08 UTC ( #6535=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm playing with sockets (I'm on 'use Socket' not 'use IO::Socket' - I want to play with the low-level stuff then I'll look at the high-level version) I'm doing ok except for the infuriating 'does the same as the system call of the same name' which I find thoughout the manual. Problem is a windows system doesn't document unix system call very well! - Back to the point - my accept is working ok - but is a 'blocking' call (i.e: waits until data arrives before returning). I assume there is a non-blocking version of accept which I can use to check if there is data present but will return immediately if none is present. Problem is I don't know how to do this. I'm assuming it's a setsockopt of some kind - or a parameter to accept, but the manual won't tell me...;-(. Help please. Many thanks - cool web site by the way! Richard.

Replies are listed 'Best First'.
Re: How do I do a non-blocking accept?
by thecap (Initiate) on Apr 07, 2000 at 07:09 UTC
    You should check out perl-chat in Tkil's Perl Examples. It uses the low level calls to select, sysread and syswrite. The diffcult thing about using select is that you can't use <SOCK> and print SOCK with nonblocking io.

    When you move to the higher level IO::* you might find Tkil's port-forward a useful guide.

Re: How do I do a non-blocking accept?
by chromatic (Archbishop) on Mar 30, 2000 at 22:01 UTC
    My notes recommend something like this (assuming Connection is your socket descriptor?):
    use Fcntl; fcntl(Connection, F_SETFL, O_NONBLOCK) or die "can't set non blocking: $!";
    I suppose you could also wrap your Socket->accept() in alarm() calls....
Re: How do I do a non-blocking accept?
by Matts (Deacon) on Aug 25, 2004 at 11:06 UTC
    First, you setup your server:
    my $server = IO::Socket::INET->new( %params, Blocking => 0 );
    Then make it non-blocking, for perls that don't obey the Blocking param above:
    IO::Handle::blocking($server, 0);
    Then you add that server to your select vector watching for read events. When a client is waiting to be accept()ed, the select will return your server as ready to read. Just compare the sockets using == to determine if the socket is your server, and if it is, issue accept(). Note that by the time you get to it the client may have changed his mind, and so your accept could return EWOULDBLOCK or EAGAIN, so you have to check for that.
Re: How do I do a non-blocking accept?
by mattr (Curate) on Sep 01, 2000 at 09:24 UTC
    If you like playing with lowlevel interfaces, you might like to install Cygwin ( which will give you a unix shell and a basic system with compiler, man pages, etc. Then maybe you could download packages from and read their manpages or try them out from the command line. Seems to use Unix sockets with the option of recompiling things to use Windows sockets according to the faq.

    Hope this helps,

Re: How do I do a non-blocking accept?
by btrott (Parson) on Mar 31, 2000 at 01:57 UTC
    Also, you may already know this, but if you use the non-blocking accept, I believe you can check $! for EAGAIN (or EWOULDBLOCK on BSD and perhaps other systems) to check whether there are no connection requests (as opposed to accept just failing for some other reason). Maybe not on your system, though...

    As an aside: I know it's quite annoying to be pointed towards man pages that you don't have on your system... here's a good source of man pages for OpenBSD, and here's some docs (in troff source) for Unix Version 7.

Re: How do I do a non-blocking accept?
by Anonymous Monk on Nov 07, 2001 at 14:32 UTC

    THIS WORKS!!!!

    (Tested on Win32 with indigo and activestate perl)

    while(1) {
     $rc=select($rout1=$bits1,$wout1=$bits1,$eout1=$bits1,0.5); # poll
     print "select($rout1,$wout1,$eout1,0)=$rc\n";

    When there's a connection, $rout1 gets set.

Re: How do I do a non-blocking accept?
by davidnicol (Acolyte) on Aug 22, 2004 at 04:48 UTC
    you have to set the listening socket to nonblocking, as documented in the man page for accept. This can be done with fcntl rather than setsockopt. As explained above here at How do I do a non-blocking accept?.
Re: How do I do a non-blocking accept?
by davidnicol (Acolyte) on Aug 23, 2004 at 01:46 UTC
    I was flummoxed by the lack of the nonblocking flags on sockets on microsoft windows, until I realized that inside a nonblocking accept(2) call, accept(2) is just going to have to do something like a select(2).

    So a non-blocking accept IS NEVER REQUIRED because you can either

    • just accept one connection per iteration -- the other ones will still be there on the next iteration or
    • When you have a hot listening socket, accept the first connection AND THEN SELECT AGAIN ON IT AND ONLY IT.

    So instead of

    foreach (@Listeners){ vec($rout,fileno($_),1) or next; # listener is nonblocking, goes until # expected accept failure while (accept(my $NewServer, $_)){ push @Clients, $NewServer
    you just do do
    foreach (@Listeners){ vec($rout,fileno($_),1) or next; # listener is blocking, but we # know this listener is hot if (accept(my $NewServer, $_)){ push @Clients, $NewServer }else{ log "accept: $!" }
    Or, mock up the accept-em-all-NOW method without clumsily making accept fail:
    foreach (@Listeners){ vec($rout,fileno($_),1) or next; # listener is blocking, but we # know this listener is hot acc: accept(my $NewServer, $_) and push @Clients, $NewServer; # select again to see if there's another my $rvec; vec($rvec,fileno($_),1) = 1; select($rvec,undef,undef,0); vec($rvec,fileno($_),1) and goto acc;

    The difference is

    by accepting all connections immediately we will possibly have more connections going, more suddenly. If we have a limit on our number of open connections, we only need to check it once per loop to keep from overrunning it.

    How much can it affect throughput? It's like asking is it better for an office building to have a one-person revolving door that spins fast or a family-size one that spins slow.

Re: How do I do a non-blocking accept?
by posicat (Initiate) on Oct 11, 2004 at 19:54 UTC
    I spent a few hours and finally found this paramater you can pass to the IO::Socket::INET ... Timeout =>
    my $sock = new IO::Socket::INET ( LocalPort => '1401', Proto => 'tcp', Listen => 1, Reuse => 1, Timeout => .1, );
    After .1 seconds it times out the accept command and continues on through your loop happily. As an added benefit this helps you prevent race conditions.
Re: How do I do a non-blocking accept?
by Anonymous Monk on Mar 27, 2002 at 04:23 UTC
    fcntl(sockfd,F_SETFL,FNDELAY) can be used to set the file descriptor in to a non blocking mode, any blocking system call on this descriptor including accept will return immediately and set the errno=EWOULDBLOCK regards rakesh soni
Re: How do I do a non-blocking accept?
by Chaosje (Initiate) on Mar 19, 2016 at 15:28 UTC
    Under Windows this will work:
    if ($^O =~ /win/i) { my $nonblocking=1; ioctl($socket, 0x8004667e, \$nonblocking); }
Re: How do I do a non-blocking accept?
by dl748 (Initiate) on Jun 02, 2001 at 02:53 UTC
    ACCEPT is a blocking function. Under Unix/perl i know you can't set it up as nonblocking.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://6535]
Approved by davido
[stevieb]: I have fixed a boatload of issues across several of my distributions, including a couple that have been nagging for a very long time and were exceptionally difficult to solve. Saving $ before we move, so thought I'd have a code session...
[stevieb]: ...session weekend. Went far better than I could have imagined. Even got a bunch of stuff soldered for another one of my electronics projects on the go, and am working on a fix for a MetaCPAN::Client issue I found
[shmem]: the smaller your boat is, the smaller is the load...
shmem is going to look for problems with C++. Urgh.
choroba has worked on the Pull Request Challenge
[stevieb]: shmem I had to do that yesterday and earlier today (C++ issues). It was only fun after I figured it all out.
[stevieb]: it won't be long before I likely won't have much time to do a lot of coding...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (5)
As of 2017-06-25 22:26 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (571 votes). Check out past polls.