Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: What's the best way to find an unused TCP port on the local system

by ikegami (Patriarch)
on Oct 20, 2006 at 17:39 UTC ( [id://579654]=note: print w/replies, xml ) Need Help??


in reply to What's the best way to find an unused TCP port on the local system

If using socket

Bind to port zero. The system will pick an unused port. You can find out the number of the port to which the socket was bound as follows:

use Socket qw( sockaddr_in ); my $port = (sockaddr_in(getsockname(SOCK)))[0]; print("Listening to port $port.\n");

If using IO::Socket/IO::Socket::INET

Don't specify a LocalPort or use LocalPort => 0. The system will pick an unused port. You can find out the number of the port to which the socket was bound as follows:

my $port = $sock->sockport(); print("Listening to port $port.\n");

Update: Added IO::Socket method.

Replies are listed 'Best First'.
Re^2: What's the best way to find an unused TCP port on the local system
by blazar (Canon) on Oct 20, 2006 at 19:49 UTC

    I have one more question. I'm interested in this problem of finding an unused port on a local system too. It's for some client/server based IPC. Given any method of those mentioned here (I prefer yours most), how would I go to communicate it to possible clients? One way could be to write that info into a (configuration) file, as the OP suggests. But that is somewhat unsatisfactory because if I wanted to make the processes communicate through files I may have chosen to do by means e.g. of a named pipe in the first place.

    Of course I may set up a predefined port, and failing that, use a workaround. On the client side, if the server doesn't respond, and only then, the client itself may check a suitable file. However how do people generally deal with this problem? (If it is a problem at all...)

      It's hard to answer without knowing what you are doing. What's the difference between the server on port A and the one on port B? Or rather, why would someone want to connect to the server on port A as opposed to one on port B?

      Generically speaking, the problem is the same as finding a someone's phone number. How do you that? Maybe you search a directory. Maybe you ask someone who knows. In both of these, you query an external system.

      Therefore, a possible solution is to have the server communicate it's vitals to a directory server. The client (user or program) then selects the server to which it wishes to connect from the directory.

      For example, ICQ used to work this way (before changes were made to fight spam and privacy invasion). The ICQ client would become a server and then connect to the central ICQ server. Someone wishing to send you a message would query the central ICQ server for your IP address.

      Another example is battle.net. People wishing to play Starcraft over the internet log into the battle.net chat server (through the game). When someone creates (hosts) a game, Starcraft contacts battle.net letting it know at which IP the game resides. battle.net would present a list of running games to users and passes on the IP address and port to people wanting to join.

      Update: Added examples.

      portmap is the traditional UNIX RPC way of doing this. It has just one service on a well-known port, which allows you to ask for a service by name and get the port it's currently running on.

      It may be overkill for your application, but maybe implementing something simpler with a SOAP interface would work.

Re^2: What's the best way to find an unused TCP port on the local system
by DrWhy (Chaplain) on Oct 20, 2006 at 19:54 UTC
    That's a good trick to know, but it won't work for me, since the server I'm starting is written in C++. My Perl code is an external controller for the server and will also act as a client. (UPDATE: FYI it's a test script)

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

      This is not a Perl "trick". It's a feature of the system's socket library. You can use port 0 in C++ as well.
        It must be a feature only of Unix(-like) systems, then. I'm working in a Windows XP environment and just tried it out with our c++ server and instead of picking a random port it actually connected to port number 0.

        Updated: No, it works as described in the previous post. Our server is just reporting (incorrectly) that it is connected to port 0.

        --DrWhy

        "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

Re^2: What's the best way to find an unused TCP port on the local system
by shmem (Chancellor) on Oct 21, 2006 at 11:06 UTC
    Hmm... if I just want to know which next port (starting from e.g. 1025) is free, but without binding to it (e.g. to pass the port number to an external program) - how can that be done? I'm doing an (unportable) system "lsof -i :$port" in ssh chain to check whether it's busy. Is there a better (portable) way?

    cheers,

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      No, it's not possible. Such a feature would unavoidably introduce a race condition. Your child process needs to either communicate the port back to you, or must inherit the opened socket from you.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://579654]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-24 11:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found