two servers listening on same port ?

Discussion in 'Perl Misc' started by sc_wizard29@hotmail.com, Jun 19, 2006.

  1. Guest

    hi everyone,

    This ones makes me scratch my head : I'm using the following script on
    Windows and it looks like I can run two instances of it
    simultaneously...which means that I have 2 servers listening on the
    same port.

    #!/usr/bin/perl -w
    use strict;
    use Socket;
    my $port = 8080;
    my $proto = getprotobyname('tcp');
    socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
    setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die
    "setsockopt: $!";
    bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
    listen(Server,SOMAXCONN) || die "listen: $!";
    print "Server : server started on port $port\n";
    while(1) {}

    I was expecting an error like "port already in use". Am I doing
    something wrong ?
     
    , Jun 19, 2006
    #1
    1. Advertising

  2. Sisyphus Guest

    <> wrote in message
    news:...
    > hi everyone,
    >
    > This ones makes me scratch my head : I'm using the following script on
    > Windows and it looks like I can run two instances of it
    > simultaneously...which means that I have 2 servers listening on the
    > same port.
    >


    I have just been bitten by the same thing on Windows 2000 - during the
    tidying up of some server and client scripts. I started getting inconsistent
    behaviour that really had me puzzled (and irate) ... until I realised I had
    four instances of the server script running concurrently - all listening to
    the same port.

    Not sure of the "approved" method for determining whether a port is in use.
    As an interim measure I'm doing the following in an attempt to make sure I
    don't make the same mistake again:

    my $server_port = '2004'; # or whatever
    my $netstat = `netstat -an`;
    if($netstat =~ /:$server_port\s/) {die "Port already in use"}
    # Followed by code to create the server listening on
    # port $server_port

    Cheers,
    Rob
     
    Sisyphus, Jun 20, 2006
    #2
    1. Advertising

  3. Anno Siegel Guest

    Sisyphus wrote:

    >
    > <> wrote in message
    > news:...
    >> hi everyone,
    >>
    >> This ones makes me scratch my head : I'm using the following script on
    >> Windows and it looks like I can run two instances of it
    >> simultaneously...which means that I have 2 servers listening on the
    >> same port.


    [...]

    > Not sure of the "approved" method for determining whether a port is in
    > use.


    As filehandles, sockets are flock-able. An exclusive lock in the
    server should do:

    flock $server, LOCK_EX | LOCK_NB or die "port in use";

    (Untested, I can't open the port another time in the first place.)

    Anno
     
    Anno Siegel, Jun 20, 2006
    #3
  4. Sisyphus Guest

    "Anno Siegel" <-berlin.de> wrote in message
    ..
    ..
    >
    > > Not sure of the "approved" method for determining whether a port is in
    > > use.

    >
    > As filehandles, sockets are flock-able. An exclusive lock in the
    > server should do:
    >
    > flock $server, LOCK_EX | LOCK_NB or die "port in use";
    >


    Also not sure about the use of flock() on Win32. When I insert the above
    code into my server script (which runs with warnings pragma enabled) it dies
    with:

    Argument "LOCK_OZ" isn't numeric in flock at file_server.plx line 35.
    port in use at file_server.plx line 35.

    Line 35 is simply the line that implements the above code - the port is
    definitely not in use.

    From 'perldoc -f flock' I find:
    "Produces a fatal error if used on a machine that doesn't implement
    flock(2), fcntl(2) locking, or lockf(3)."

    'perldoc perlport' reports that fcntl() is not implemented on Win32, though
    flock() *is* implemented ... not sure what to make of all that.

    Sorry if I'm being dumb.

    Cheers,
    Rob
     
    Sisyphus, Jun 20, 2006
    #4
  5. Thomas Kratz Guest

    wrote:
    > hi everyone,
    >
    > This ones makes me scratch my head : I'm using the following script on
    > Windows and it looks like I can run two instances of it
    > simultaneously...which means that I have 2 servers listening on the
    > same port.
    >
    > #!/usr/bin/perl -w
    > use strict;
    > use Socket;
    > my $port = 8080;
    > my $proto = getprotobyname('tcp');
    > socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
    > setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die
    > "setsockopt: $!";


    Get rid of the SO_REUSEADDR. IIRC this will have the disadvantage that you
    may have to wait a bit before you can reopen the socket after a close.

    > bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
    > listen(Server,SOMAXCONN) || die "listen: $!";
    > print "Server : server started on port $port\n";
    > while(1) {}
    >
    > I was expecting an error like "port already in use". Am I doing
    > something wrong ?
    >


    You might find IO::Socket easier to use.

    Thomas

    --
    $/=$,,$_=<DATA>,s,(.*),$1,see;__END__
    s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
    $_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
    '%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
    print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e.r^.>l^..>k^.-
     
    Thomas Kratz, Jun 20, 2006
    #5
  6. Sisyphus Guest

    "Thomas Kratz" <> wrote in message
    ..
    ..
    >
    > You might find IO::Socket easier to use.
    >


    Yes - that's what *I* use - but it still permits multiple instances of
    servers to be listening on the same port.

    Seems to be a Win32 thing - on linux I find it's not possible to run
    multiple instances of the same server script. I get the fatal error "Address
    already in use".

    Even with the latest CPAN release of IO, the behaviour persists on Win32.
    Should this be submitted as a bug to
    http://rt.cpan.org/Public/Dist/Display.html?Name=IO ?

    Cheers,
    Rob
     
    Sisyphus, Jun 20, 2006
    #6
  7. Anno Siegel Guest

    Sisyphus wrote:

    >
    > "Anno Siegel" <-berlin.de> wrote in message
    > .
    > .
    >>
    >> > Not sure of the "approved" method for determining whether a port is in
    >> > use.

    >>
    >> As filehandles, sockets are flock-able. An exclusive lock in the
    >> server should do:
    >>
    >> flock $server, LOCK_EX | LOCK_NB or die "port in use";
    >>

    >
    > Also not sure about the use of flock() on Win32. When I insert the above
    > code into my server script (which runs with warnings pragma enabled) it
    > dies with:
    >
    > Argument "LOCK_OZ" isn't numeric in flock at file_server.plx line 35.
    > port in use at file_server.plx line 35.


    LOCK_OZ? Whazzat? Some windowy specialty?

    > Line 35 is simply the line that implements the above code - the port is
    > definitely not in use.
    >
    > From 'perldoc -f flock' I find:
    > "Produces a fatal error if used on a machine that doesn't implement
    > flock(2), fcntl(2) locking, or lockf(3)."
    >
    > 'perldoc perlport' reports that fcntl() is not implemented on Win32,
    > though flock() *is* implemented ... not sure what to make of all that.


    I have no personal experience with Windows, but I thought that file
    locking worked.

    Anno
     
    Anno Siegel, Jun 20, 2006
    #7
  8. Guest

    Looks like the use of netstat before the binding is the most "direct"
    solution...

    Here is the same script with IO::Socket (the problem is the same but
    the script is shorter ;)

    #!/usr/bin/perl -w
    use strict;
    use IO::Socket;
    my $port=8080;
    my $server = IO::Socket::INET->new(Proto => 'tcp',
    LocalPort => $port,
    Listen => SOMAXCONN,
    Reuse => 1);
    die "can't setup server" unless $server;
    print "Server : server started on port $port\n";
    while(1) {}
     
    , Jun 20, 2006
    #8
  9. Ben Morrow Guest

    Quoth -berlin.de:
    > Sisyphus wrote:
    >
    > >
    > > <> wrote in message
    > > news:...
    > >> hi everyone,
    > >>
    > >> This ones makes me scratch my head : I'm using the following script on
    > >> Windows and it looks like I can run two instances of it
    > >> simultaneously...which means that I have 2 servers listening on the
    > >> same port.

    >
    > [...]
    >
    > > Not sure of the "approved" method for determining whether a port is in
    > > use.

    >
    > As filehandles, sockets are flock-able.


    I *seriously* doubt if they are on Win32. Sockets on Win32 are not
    ordinary filehandles, perl just fakes them up to look like it.

    To the OP: remove the SO_REUSEADDR. Winsock is *COMPLETELY* broken;
    among other things, SO_REUSEADDR doesn't mean 'allow another process to
    bind again after the socket is closed but before the wait period' but
    actually means 'bind to this port even if there is another process bound
    there, at which point both sockets become non-deterministic' !!

    See http://msdn.microsoft.com/library/default.asp?url=/library/en-us
    /winsock/winsock/using_so_reuseaddr_and_so_exclusiveaddruse.asp

    (please excuse the wrapping).

    Ben

    --
    'Deserve [death]? I daresay he did. Many live that deserve death. And some die
    that deserve life. Can you give it to them? Then do not be too eager to deal
    out death in judgement. For even the very wise cannot see all ends.'
     
    Ben Morrow, Jun 20, 2006
    #9
  10. Sisyphus Guest

    "Anno Siegel" <-berlin.de> wrote in message
    ..
    ..
    >
    > LOCK_OZ? Whazzat? Some windowy specialty?
    >


    or maybe an Aussie specialty :)

    >
    > I have no personal experience with Windows, but I thought that file
    > locking worked.
    >


    Heh ... I had this notion that it worked on Win32 without even being
    specifically invoked :)

    Btw, I (inadvertently) omitted some relevant info from my reply - if I run
    under strictures I get:

    Bareword "LOCK_EX" not allowed while "strict subs" in use at file_server.plx
    line 35.
    Bareword "LOCK_NB" not allowed while "strict subs" in use at file_server.plx
    line 35.

    Without strictures the error is as I reported.

    I tried not supplying a second argument, but perl insists that a second arg
    be supplied. I'm not feeling very energetic about this at the moment ....
    maybe later :)

    Cheers,
    Rob
     
    Sisyphus, Jun 20, 2006
    #10
  11. Thomas Kratz Guest

    Sisyphus wrote:
    > "Thomas Kratz" <> wrote in message
    > .
    > .
    >
    >>You might find IO::Socket easier to use.
    >>

    >
    >
    > Yes - that's what *I* use - but it still permits multiple instances of
    > servers to be listening on the same port.


    No to me it does not. Using:

    my $srv = IO::Socket::INET->new(
    Proto => 'tcp',
    LocalPort => 4016,
    Listen => SOMAXCONN,
    ReuseAddr => 0,
    );

    the second instance fails reporting 'Unknown error' ($!).

    >
    > Seems to be a Win32 thing - on linux I find it's not possible to run
    > multiple instances of the same server script. I get the fatal error "Address
    > already in use".


    In Winsock 2 there is a new socket option called SO_EXCLUSIVEADDRUSE.
    http://msdn.microsoft.com/library/d...winsock/winsock/using_so_exclusiveaddruse.asp

    >
    > Even with the latest CPAN release of IO, the behaviour persists on Win32.
    > Should this be submitted as a bug to
    > http://rt.cpan.org/Public/Dist/Display.html?Name=IO ?


    I don't think it's a bug. More a winsock "feature".

    Thomas


    --
    $/=$,,$_=<DATA>,s,(.*),$1,see;__END__
    s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
    $_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
    '%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
    print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e.r^.>l^..>k^.-
     
    Thomas Kratz, Jun 20, 2006
    #11
  12. Ben Morrow Guest

    Quoth :
    > Looks like the use of netstat before the binding is the most "direct"
    > solution...


    No, omit the SO_REUSEADDR...

    > Here is the same script with IO::Socket (the problem is the same but
    > the script is shorter ;)
    >
    > #!/usr/bin/perl -w
    > use strict;
    > use IO::Socket;
    > my $port=8080;
    > my $server = IO::Socket::INET->new(Proto => 'tcp',
    > LocalPort => $port,
    > Listen => SOMAXCONN,
    > Reuse => 1);

    ^^^^^^^^^^^^^^
    ....or this.

    Ben

    --
    All persons, living or dead, are entirely coincidental.
    Kurt Vonnegut
     
    Ben Morrow, Jun 20, 2006
    #12
  13. Ben Morrow Guest

    Quoth "Sisyphus" <>:
    >
    > "Anno Siegel" <-berlin.de> wrote in message
    > .
    > > LOCK_OZ? Whazzat? Some windowy specialty?

    >
    > or maybe an Aussie specialty :)
    >
    > > I have no personal experience with Windows, but I thought that file
    > > locking worked.

    >
    > Heh ... I had this notion that it worked on Win32 without even being
    > specifically invoked :)


    Opening a file takes a mandatory lock, unless you ask it not to.

    > Btw, I (inadvertently) omitted some relevant info from my reply - if I run
    > under strictures I get:
    >
    > Bareword "LOCK_EX" not allowed while "strict subs" in use at file_server.plx
    > line 35.
    > Bareword "LOCK_NB" not allowed while "strict subs" in use at file_server.plx
    > line 35.
    >
    > Without strictures the error is as I reported.


    <giggle>

    If you don't import those constants from the Fcntl module, then Perl
    (without strict) will treat them as unquoted strings. Then we have

    ~% perl -le'print "LOCK_EX" | "LOCK_NB"'
    LOCK_OZ

    Have you *really* never used flock before?

    Ben

    --
    Giles: It's very common for Indian spirits to change to animal form.
    Buffy: [...] and, 'Native American'. G: Sorry? B: We don't say 'Indian'.
    G: Oh, right, yes; always behind on the terms... yes, still trying not to refer
    to you lot as 'bloody colonials'. [Buffy, 'Pangs']
     
    Ben Morrow, Jun 20, 2006
    #13
  14. Anno Siegel wrote:
    > I have no personal experience with Windows, but I thought that file
    > locking worked.


    IIRC, flock() causes a fatal error on Windows 95/98, but works on later
    Windows versions.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Jun 20, 2006
    #14
  15. Sisyphus Guest

    "Thomas Kratz" <> wrote in message
    news:4497e9b6$0$31170$-rheiner.de...
    > Sisyphus wrote:
    > > "Thomas Kratz" <> wrote in message
    > > .
    > > .
    > >
    > >>You might find IO::Socket easier to use.
    > >>

    > >
    > >
    > > Yes - that's what *I* use - but it still permits multiple instances of
    > > servers to be listening on the same port.

    >
    > No to me it does not. Using:
    >
    > my $srv = IO::Socket::INET->new(
    > Proto => 'tcp',
    > LocalPort => 4016,
    > Listen => SOMAXCONN,
    > ReuseAddr => 0,
    > );
    >
    > the second instance fails reporting 'Unknown error' ($!).
    >


    Yep - there was a stray 'Reuse => 1' in the constructor that was causing my
    problem on Windows - no doubt the result of a mindless copy'n'paste
    somewhere along the way. Removing it removed the need for that awful netstat
    kludge.

    Cheers,
    Rob
     
    Sisyphus, Jun 21, 2006
    #15
  16. Sisyphus Guest

    "Ben Morrow" <>
    ..
    ..
    >
    > Have you *really* never used flock before?
    >


    Yep.
    Does it show ?

    Cheers,
    Rob
     
    Sisyphus, Jun 21, 2006
    #16
  17. Guest

    Thanks everyone for your answers... here are two versions of a simple
    server that "solve" the multiple binding problem on windows (for the
    ones too busy to read all the replies ;)

    #!/usr/bin/perl -w
    use strict;
    use Socket;
    my $port = 2000;
    my $proto = getprotobyname('tcp');
    socket(Server, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
    bind(Server, sockaddr_in($port, INADDR_ANY)) || die "bind: $!";
    listen(Server,SOMAXCONN) || die "listen: $!";
    print "Server : server started on port $port\n";
    while(1) {}

    #!/usr/bin/perl -w
    use strict;
    use IO::Socket;
    my $port=8080;
    my $server = IO::Socket::INET->new(Proto => 'tcp',
    LocalPort => $port,
    Listen => SOMAXCONN);
    die "can't setup server" unless $server;
    print "Server : server started on port $port\n";
    while(1) {}
     
    , Jun 21, 2006
    #17
  18. Big and Blue Guest

    Ben Morrow wrote:
    >
    > To the OP: remove the SO_REUSEADDR. Winsock is *COMPLETELY* broken;


    I think you've missed the point - Microsoft *is* the standard (the MS
    definition of a standard is "used by MS"). It's everything else which is
    wrong. The fact that MS is completely broken here doesn't matter....


    --
    Just because I've written it doesn't mean that
    either you or I have to believe it.
     
    Big and Blue, Jun 22, 2006
    #18
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bob Garbados
    Replies:
    5
    Views:
    475
    Bob Garbados
    Dec 22, 2004
  2. kai
    Replies:
    6
    Views:
    603
    Steven Cheng[MSFT]
    Nov 28, 2005
  3. Pif Paf
    Replies:
    4
    Views:
    1,633
    Irmen de Jong
    Feb 24, 2004
  4. Thomas W
    Replies:
    1
    Views:
    284
  5. bluebaron
    Replies:
    3
    Views:
    773
    Jonathan N. Little
    Nov 4, 2009
Loading...

Share This Page