http://www.perlmonks.org?node_id=1063015


in reply to How to count the number of pending clients in socket queue?

You can't tell how many are waiting to be accepted, but you can tell if there are "zero" or "one or more" waiting. You don't provide much detail, but I assume you might be asking this so that you can avoid blocking on accept(). If that's the case, this example might be helpful.

#!/usr/bin/perl use strict;use warnings; use IO::Select; use IO::Socket; use Data::Dumper; $Data::Dumper::Terse = 1; $Data::Dumper::Useqq = 1; $Data::Dumper::Indent = 0; # unbuffer STDOUT so you can watch the output real time select STDOUT;$| = 1; # create a listen socket, on port 7777 my $l = IO::Socket::INET->new( Listen => 1, LocalPort => 7777, ReuseAddr => 1 ) or die("Can't listen: $!\n"); # create an IO::Select object my $sel = IO::Select->new($l); my $timeout = 0.1; my @waiting; while (1) { # @waiting -> sockets with "something ready to read", # (including the listen socket) @waiting = $sel->can_read($timeout); my $nwaiting = scalar(@waiting); printf "%d sockets are readable...\n", $nwaiting; if ($nwaiting) { foreach my $fh (@waiting) { if ( $fh == $l ) { # listener has a new connection for us... print "\tlistener accepting connection..\n"; my $newconn = $l->accept(); # add this new connection to the select mask $sel->add($newconn); } else { # one of the connected clients wrote something to us print "\tsocket has unread data\n"; my $buf; # read 255 byte chunk. if they sent more # than that, we'll get it the next go-round if ( $fh->sysread( $buf, 255 ) ) { printf "\tgot [%s] from socket\n", Dumper($buf); } else { # client disconnected print "\t client gone, closing socket\n"; $fh->close(); $sel->remove($fh); } # read from $fh here... } } } else { print "\tyou could do other stuff here...\n"; } # sleep to avoid a tight loop # probably too long for a real app, but useful # to watch STDOUT in real time sleep(2); }

Replies are listed 'Best First'.
Re^2: How to count the number of pending clients in socket queue?
by mrbark (Acolyte) on Nov 18, 2013 at 01:40 UTC

    Thanks for your answer guys.

    I have no blocking problem, my process has nothing to do while waiting. I would just need this information to know when I need to add a new server to the load balancing network...

    In theory my system shouldn't have more than 1 client waiting to be accepted, otherwise I want to add a server.

    Is there any way to know in /proc e.g. or any other system/kernel way?

    Thanks!

      No, there's not an easy way to see that. The /proc info, lsof, ss, etc, don't show the current listenq depth. However, there are pretty robust pieces of software that are able to determine when to spin up more theads/instances/processes without using that information. Most of them use the "I'm out of spare workers...they are all busy" condition as the trigger to add more resources..not "work is piling up at the front door" event, which is what the current listenq depth is.

        Greetings, kschwab.

        Let me preface the following, by letting you know, I'm not trying to be argumentative. :)

        I should also note; that I'm speaking from a *BSD box. So this might explain differences.

        'nuff said.
        So my experiences seem to be a bit different. For example. My last log entry (somewhat abreviated):

        :8090 tcpflags 0x2<SYN>; tcp_input: Connection attempt to closed port
        Is fairly informative. I can also get pretty detailed information from netstat, and lsof: WAIT, LISTEN, ...

        I cant speak for Linux, or OSX, for that matter (altho OSX uses BSD). But at least on BSD, it seems like I could get that sort of information. I'll look a bit deeper, and see if I can get the kind of output the OP's looking for.

        --Chris

        #!/usr/bin/perl -Tw
        use Perl::Always or die;
        my $perl_version = (5.12.5);
        print $perl_version;
      Greetings, mrbark.

      As it appears you're on a *NIX box. Aside from poll. The man pages for ifconfig, lsof, netstat, etc. Might give you some interesting information, that you could ask Perl to provide you in informative, and useful ways. :)

      HTH

      --Chris

      #!/usr/bin/perl -Tw
      use Perl::Always or die;
      my $perl_version = (5.12.5);
      print $perl_version;
      I believe (not 100% sure but seems to work on my Debian with 3.10.3 kernel) that in /proc/net/tcp the sockets in listen-state have a state-code of "0A" and for those the receive-queue entry holds the number of pending (i.e. not yet accepted) connections.

      This is how such an entry looks like:

      1: 00000000:1A0B 00000000:0000 0A 00000000:00000002 00:00000000 00000000  1000        0 1117932 1 ffff880031e70040 100 0 0 10 0

      The fist column is the local address (here a server-socket listening on port 6667) the next the remote address, then the state (here 0A for listening) then the transmit and receive queue-lengths.

      Here my server has 2 connections pending.

      So using the address your server listens you should be able to extract the information you need from /proc/net/tcp.

      Maybe Linux::Proc::Net::TCP can help here, but I have never used it.

        Awesome! Thank you. Work on Slackware too, and if it works on Slack that means it is a Linux standard. I never thought there was a file like this, perfect!