BrowserUk has asked for the wisdom of the Perl Monks concerning the following question:

Has anyone encountered and resolved the cause of either or both of the following error values when using IO::Socket::INET on Win32?

Error 10048 - Only one usage of each socket address (protocol/network +address/port) is normally permitted. Error 10061 - No connection could be made because the target computer +actively refused it.

Both errors are being produced by simple clients attempting to connect to a local server. The problems only occur when running large numbers of concurrent clients attempting to connect to the same server port. The server appears healthy, but once the second error starts to occur, it rapidly gets more frequent until it reaches the point where no connection is accepted, even a single connect using telnet.

Is there a method for determining (from within the server application), if a listening socket has "stopped listening" for some reason?

Should $server->connected return anything useful to indicate that the listener is healthy, even if there is currently no client active?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: IO::Socket::INET on Win32 (SO_REUSEADDR)
by tye (Sage) on Feb 28, 2006 at 17:33 UTC

    EADDRINUSE (your first one) is a socket programming FAQ. You need to set SO_REUSEADDR (which is what you should do for servers trying to use a well-known port number).

    The second one could be quite a few things, and you'll probably have to do some debugging work. My first guess is that you are leaking request notifications so your listen queue is backing up. But I don't have much confidence in diagnosing that problem from just the brief description of the symptom. It could also be that your server is getting bogged down for any number of reasons and just responding to connection requests more and more slowly.

    You can specify a larger listen queue size when you set up the socket. You can also set a larger receive buffer via SO_RCVBUF.

    I suspected there was a way to query how many connection requests are currently in the queue, but I don't see such.

    - tye        

      Thanks for the response.

      The server is using SO_REUSEADRR (I think?) and an extended queue

      use IO::Socket::INET; my $server = IO::Socket::INET->new( LocalPort => 9000, Listen => 1000, Reuse => 1. ) or die "Create listner failed with: $! [$^E]";

      but the confusing thing is that I am seeing no errors from the server, only the clients. For testing I am using this client:

      #! perl -slw use strict; use List::Util qw[ shuffle ]; use IO::Socket::INET;; our $N ||= 10000; my $cno = shift; for ( 1.. $N ) { warn $_; # <STDIN>; my $c = IO::Socket::INET->new( 'localhost:9000' ) or do{ warn "\a\n\n\t\t*** $cno ($_): Connect failed with [$^E] ***\n +\n\a"; sleep 10; next; }; $c->shutdown( 2 ) or warn "Shutdown failed with $^E\n" }

      And starting multiple copies like this

      c:\test>for /l %i in (1,1,10) do @start /b serialClient.pl %i

      If I uncomment the <STDIN>; line, and start 10 (or 20 or 50) copies, and hold down the enter key, I get anywhere from 3,500 to 10,000 connect/shutdown cycles by each client, cleanly before the errors start to occur (in the clients). When the errors occur, all activity in the server ceases for a while, 5 to 15 seconds. If I wait until the server starts servicing (queued) connects again and then hold the return key down, everything is fine again and all the clients are able to complete the connect/shutdown cycle again as fast as the machine allows them to run.

      Sometimes this happy state continues till the end of the run; sometimes the error condition reoccurs, with identical symptomsm, and can again be cured by pausing the clients until the server starts to show activity again.

      I also have a version of the client that conducts a conversation with the server, passing a url and retrieving the content from it as gathered by the server (being served from diskcache to alleviate the narrowness of my connection). When the clients start being unable to get a new connection--those already connected continue to retrieve their data without errors.

      When the clients are unable to connect, the server shows no unusual activity. It is multithreaded with the actual conversations be handed off to a pool of threads once the accept is returned. If the clients simply disconnect, the thread pool remains basically inactive and the main thread with the accept loop doesn't appear to be shuffling memory or anything.

      I've also tried disconnecting from the internet and terminating my firewall to exclude that from the equation with no change.

      It's like the server just decides to stop accepting requests for a while until thing quieten down. I'm beginning to suspect that the problem is deeper than Perl and lies somewhere in the protocal stack?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: IO::Socket::INET on Win32
by InfiniteSilence (Curate) on Feb 28, 2006 at 19:49 UTC
    I am curious to see if this is really the server that is the root cause for the slowdown or the client. Can you try it again -- this time when the server shows signs of slowing down, move to another machine and fire more clients?

    Celebrate Intellectual Diversity

      That's a very good thought. Thanks.

      I don't have another machine to use at the moment. I could expose the port and get someone to connect externally. I may also try resurrecting my dead portable and see if I can get that to network with my machine.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.