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

2019-01-01 16:59发布

In C# to use a TcpClient or generally to connect to a socket how can I first check if a certain port is free on my machine?

more info: This is the code I use:

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

18条回答
路过你的时光
2楼-- · 2019-01-01 17:19

If I'm not very much mistaken, you can use System.Network.whatever to check.

However, this will always incur a race condition.

The canonical way of checking is try to listen on that port. If you get an error that port wasn't open.

I think this is part of why bind() and listen() are two separate system calls.

查看更多
刘海飞了
3楼-- · 2019-01-01 17:19

From the avalaible ports i would exclude:

  • active TCP connections
  • active TCP listeners
  • active UDP listeners

With the following import:

using System.Net.NetworkInformation;

You can use the following function to check if a port is avalaible or not:

private bool isPortAvalaible(int myPort)
{
    var avalaiblePorts = new List<int>();
    var properties = IPGlobalProperties.GetIPGlobalProperties();

    // Active connections
    var connections = properties.GetActiveTcpConnections();
    avalaiblePorts.AddRange(connections);

    // Active tcp listners
    var endPointsTcp = properties.GetActiveTcpListeners();
    avalaiblePorts.AddRange(endPointsTcp);

    // Active udp listeners
    var endPointsUdp = properties.GetActiveUdpListeners();
    avalaiblePorts.AddRange(endPointsUdp);

    foreach (int p in avalaiblePorts){
        if (p == myPort) return false;
    }
    return true;
}

I give you a similar function for those who use VB.NET:

Imports System.Net.NetworkInformation
Private Function isPortAvalaible(ByVal myPort As Integer) As Boolean
  Dim props As IPGlobalProperties = IPGlobalProperties.GetIPGlobalProperties()

  ' ignore active connections
  Dim tcpConnInfoArray() As TcpConnectionInformation = props.GetActiveTcpConnections()
  For Each tcpi As Net.NetworkInformation.TcpConnectionInformation In tcpConnInfoArray
    If tcpi.LocalEndPoint.Port = myPort Then
      Return False
    End If
  Next tcpi

  ' ignore active TCP listeners
  Dim activeTcpListeners() As Net.IPEndPoint = props.GetActiveTcpListeners
  For Each tcpListener As Net.IPEndPoint In activeTcpListeners
    If tcpListener.Port = myPort Then
      Return False
    End If
  Next tcpListener

  ' ignore active UPD listeners
  Dim activeUdpListeners() As Net.IPEndPoint = props.GetActiveUdpListeners
  For Each udpListener As Net.IPEndPoint In activeUdpListeners
    If udpListener.Port = myPort Then
      Return False
    End If
  Next udpListener

  Return True
End Function
查看更多
荒废的爱情
4楼-- · 2019-01-01 17:21

Check for error code 10048

try
{
    TcpListener tcpListener = new TcpListener(ipAddress, portNumber);
    tcpListener.Start();
}
catch(SocketException ex)
{
    if(ex.ErrorCode == 10048)
    {
        MessageBox.Show("Port " + portNumber + " is currently in use.");
    }
    return;
}
查看更多
零度萤火
5楼-- · 2019-01-01 17:23

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.

查看更多
高级女魔头
6楼-- · 2019-01-01 17:24

Be aware the time window between you make check and the moment you try to make connection some process may take the port - classical TOCTOU. Why don't you just try to connect? If it fails then you know the port is not available.

查看更多
何处买醉
7楼-- · 2019-01-01 17:26

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.
查看更多
登录 后发表回答