In C#, how to check if a TCP port is available?

34

Solution 1

Since you're using a TcpClient, that means you're checking open TCP ports. There are lots of good objects available in the System.Net.NetworkInformation namespace.

Use the IPGlobalProperties object to get to an array of TcpConnectionInformation objects, which you can then interrogate about endpoint IP and port.


 int port = 456; //<--- This is your value
 bool isAvailable = true;

 // Evaluate current system tcp connections. This is the same information provided
 // by the netstat command line application, just in .Net strongly-typed object
 // form.  We will look through the list, and if our port we would like to use
 // in our TcpClient is occupied, we will set isAvailable to false.
 IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
 TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();

 foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
 {
   if (tcpi.LocalEndPoint.Port==port)
   {
     isAvailable = false;
     break;
   }
 }

 // At this point, if isAvailable is true, we can proceed accordingly.

Solution 2

You're on the wrong end of the Intertube. It is the server that can have only one particular port open. Some code:

  IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
  try {
    TcpListener tcpListener = new TcpListener(ipAddress, 666);
    tcpListener.Start();
  }
  catch (SocketException ex) {
    MessageBox.Show(ex.Message, "kaboom");
  }

Fails with:

Only one usage of each socket address (protocol/network address/port) is normally permitted.

Solution 3

When you set up a TCP connection, the 4-tuple (source-ip, source-port, dest-ip, dest-port) has to be unique - this is to ensure packets are delivered to the right place.

There is a further restriction on the server side that only one server program can bind to an incoming port number (assuming one IP address; multi-NIC servers have other powers but we don't need to discuss them here).

So, at the server end, you:

  • create a socket.
  • bind that socket to a port.
  • listen on that port.
  • accept connections on that port. and there can be multiple connections coming in (one per client).

On the client end, it's usually a little simpler:

  • create a socket.
  • open the connection. When a client opens the connection, it specifies the ip address and port of the server. It can specify its source port but usually uses zero which results in the system assigning it a free port automatically.

There is no requirement that the destination IP/port be unique since that would result in only one person at a time being able to use Google, and that would pretty well destroy their business model.

This means you can even do such wondrous things as multi-session FTP since you set up multiple sessions where the only difference is your source port, allowing you to download chunks in parallel. Torrents are a little different in that the destination of each session is usually different.

And, after all that waffling (sorry), the answer to your specific question is that you don't need to specify a free port. If you're connecting to a server with a call that doesn't specify your source port, it'll almost certainly be using zero under the covers and the system will give you an unused one.

Solution 4

Thanks for this tip. I needed the same functionality but on the Server side to check if a Port was in use so I modified it to this code.

 private bool CheckAvailableServerPort(int port) {
    LOG.InfoFormat("Checking Port {0}", port);
    bool isAvailable = true;

    // Evaluate current system tcp connections. This is the same information provided
    // by the netstat command line application, just in .Net strongly-typed object
    // form.  We will look through the list, and if our port we would like to use
    // in our TcpClient is occupied, we will set isAvailable to false.
    IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
    IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();

    foreach (IPEndPoint endpoint in tcpConnInfoArray) {
        if (endpoint.Port == port) {
            isAvailable = false;
            break;
        }
    }

    LOG.InfoFormat("Port {0} available = {1}", port, isAvailable);

    return isAvailable;
}

Solution 5

TcpClient c;

//I want to check here if port is free.
c = new TcpClient(ip, port);

...how can I first check if a certain port is free on my machine?

I mean that it is not in use by any other application. If an application is using a port others can't use it until it becomes free. – Ali

You have misunderstood what's happening here.

TcpClient(...) parameters are of server ip and server port you wish to connect to.

The TcpClient selects a transient local port from the available pool to communicate to the server. There's no need to check for the availability of the local port as it is automatically handled by the winsock layer.

In case you can't connect to the server using the above code fragment, the problem could be one or more of several. (i.e. server ip and/or port is wrong, remote server not available, etc..)

Share:
34
michelleedward
Author by

michelleedward

Updated on November 26, 2020

Comments

  • michelleedward
    michelleedward over 3 years

    I am busy coding a program in netbeans (java)for a school project. It has multiple JFrames. I just figured out how to make each frame full screen, but now all the elements are in the wrong places. What do I do? Is there a way for me to make sure that the elements are fixed and don’t move? Thank you

  • Ali
    Ali over 15 years
    I am the one trying to connect to a socket. I have edited the question to make it more clear.
  • Ali
    Ali over 15 years
    I am using .NET 3.5 and I can't fine that.
  • Ali
    Ali over 15 years
    If my application try to connect using port 10 and another instance of my application try to connect using port 10 again it will fail because both applications can't send data using one port, when it comes to receiving data i.e. port 80 that is different
  • Moose
    Moose over 15 years
    if it fails when the second instance tries to connect, it is the listening application, not your application.
  • Moose
    Moose over 15 years
    That's where I was going with it too. Someone is definitely confused here, and it's possible it me.
  • jro
    jro about 15 years
    Good point, very possible. Not sure one can lock or mutex their way to exclusive access to a port.
  • Dave Van den Eynde
    Dave Van den Eynde about 15 years
    It is possible that the client requires a certain port too, but it's not common.
  • user772401
    user772401 about 15 years
    How is this relevant to the question? This answer deals with local ports, not remote ports.
  • jro
    jro about 15 years
    It's relevant in that it answers the OP's request. The local/remote difference notwithstanding (totally agree with you), the OP's requirement was to create a new TcpClient with a port that is "free".
  • JoeBilly
    JoeBilly almost 13 years
    Note that this code only check active connections. The connections which don't have sent or received packets will not be listed.
  • Mike de Klerk
    Mike de Klerk over 11 years
    Compare the result of the code above to netstat -a -b. Notice that LISTENING connections are not present in the GetActiveTcpConnections(). You should also check in System.Net.IPEndPoints[] returned by ipGlobalProperties.GetActiveTcpListeners();
  • Csaba Toth
    Csaba Toth about 11 years
    That is good for checking a set of given sockets. The question is about just one socket (which port number maybe undetermined though (?))
  • Csaba Toth
    Csaba Toth about 11 years
    I like this code the best, this really opens up a TCP connection to a socket just to peek if someone is listening on the other end or not. And I think many people actually want this, when they want to "test if a port is open on a remote host". There is a bug however in the above code: if (sock.Connected == true) then the port is open for connections, some server-like software is listening there. If there's a SocketException with a 10061 ErrorCode (message "(0x80004005): No connection could be made because the target machine actively refused it" then the port is closed!
  • Csaba Toth
    Csaba Toth about 11 years
    So it's the other way around then in the code snippet. Another note: if someone would try Dns.GetHostEntry in such test setup where you have virtual servers with only IP addresses, you gonna have an exception.
  • Csaba Toth
    Csaba Toth about 11 years
    TOCTOU is YALAIHHOBIKTPBI (Yet Another Long Abbreviation I Haven't Heard Of, But I Know the Phenomena Behind It)
  • user207421
    user207421 about 9 years
    You can create a TcpClient with a local port that is free by specifying zero as the local port. None of this is necessary, and it is liable to a major timing-window problem.
  • user207421
    user207421 about 9 years
    You don't need this. Just specify port zero.
  • user207421
    user207421 about 9 years
    Just try to listen on it yourself. You don't need any of this.
  • Glubus
    Glubus over 8 years
    When posting some code, try to elaborate on why it is the solution to the problem. Just code might be too little information and your answer risks being looked over.
  • BrainSlugs83
    BrainSlugs83 over 8 years
    @jro -- the TcpClient class will always use a port that is free (the port in the constructor that the op asked about is for the remote endpoint! -- local outgoing ports are always auto assigned by winsocks, and you do not have control over them!). -- This is useful for TcpServer, etc. -- but I'm not sure how useful it will be for whatever the heck the op is trying to do.
  • BrainSlugs83
    BrainSlugs83 over 8 years
    @DaveVandenEynde that can only happen if the "client" is actually "serving" something on that particular port (making it a "server", at least for that port, as far as TCP is concerned). -- When you have a client TCP connection, you don't get to control the outgoing port. The TCP stack assigns you an outgoing port, and you don't have any control over it.
  • Dave Van den Eynde
    Dave Van den Eynde over 8 years
    @BrainSlugs83 You most certainly can: stackoverflow.com/questions/2869840/…
  • Kraang Prime
    Kraang Prime about 7 years
    The note in the source code comment : "This is the same information provided by the netstat command line application" -- is a lie. It does not provide the same information as the netstat command also provides the PID of the application using the port (-anb) and without any parameters it shows Foreign connection as well as state.
  • bgh
    bgh over 4 years
    This is a valid bit of code to check if the port is free. Just remember to Stop() the TcpListener in case it succeeds (unless you intend to use that same TcpListener object to start listening on the port).