在C#中,如何检查TCP端口是否可用?

Ali*_*Ali 116 .net c# tcp tcpclient

在C#中使用TcpClient的或一般连接到插座我怎么能先检查如果某个端口是免费在我的机器上?

更多信息: 这是我使用的代码:

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

jro*_*jro 207

由于您正在使用a TcpClient,这意味着您正在检查打开的TCP端口.System.Net.NetworkInformation命名空间中有许多可用的好对象.

使用该IPGlobalProperties对象获取对象数组,TcpConnectionInformation然后可以查询端点IP和端口.


 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.
Run Code Online (Sandbox Code Playgroud)

  • 请记住,在检查时,另一个进程可以绑定到该端口. (37认同)
  • 将上面代码的结果与`netstat -a -b`进行比较.请注意,`GetActiveTcpConnections()`中不存在`LISTENING`连接.你还应该检查`ipGlobalProperties.GetActiveTcpListeners();`返回的`System.Net.IPEndPoints []`. (28认同)
  • 请注意,此代码仅检查活动连接.不会列出没有发送或接收数据包的连接. (7认同)
  • 它的相关之处在于它满足了OP的要求.虽然本地/远程差异(完全同意你),OP的要求是创建一个新的TcpClient,其端口是"免费的". (6认同)
  • 这与问题有什么关系?该答案处理的是* local *端口,而不是* remote *端口。 (2认同)

Han*_*ant 43

你在Intertube的错误一端.服务器只能打开一个特定端口.一些代码:

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

失败:

通常只允许使用每个套接字地址(协议/网络地址/端口).

  • 客户端也可能需要某个端口,但这并不常见. (3认同)
  • 这是检查端口是否空闲的有效代码。只需记住 Stop() TcpListener,以防成功(除非您打算使用相同的 TcpListener 对象开始侦听端口)。 (2认同)

pax*_*blo 19

设置TCP连接时,4元组(source-ip,source-port,dest-ip,dest-port)必须是唯一的 - 这是为了确保数据包被传送到正确的位置.

服务器端还有一个限制,即只有一个服务器程序可以绑定到一个传入端口号(假设一个IP地址;多个NIC服务器有其他权限,但我们不需要在这里讨论它们).

那么,在服务器端,您:

  • 创建一个套接字.
  • 将该套接字绑定到端口.
  • 听那个港口.
  • 接受该端口上的连接.并且可以有多个连接(每个客户端一个).

在客户端,它通常有点简单:

  • 创建一个套接字.
  • 打开连接.当客户端打开连接时,它指定服务器的IP地址和端口.它可以指定其源端口,但通常使用零,这会导致系统自动为其分配一个空闲端口.

没有要求,目标IP /端口是唯一的,因为这将导致只有一个人在同一时间能够使用谷歌,这将很好摧毁他们的商业模式.

这意味着您甚至可以执行多会话FTP这样的奇妙事情,因为您设置了多个会话,其中唯一的区别是您的源端口,允许您并行下载块.Torrent有点不同,因为每个会话的目的地通常是不同的.

而且,经过所有的胡扯(抱歉),您的具体问题的答案是您不需要指定一个自由端口.如果您使用未指定源端口的呼叫连接到服务器,则几乎可以肯定是在封面下使用零,系统将为您提供未使用的端口.


Ind*_*000 15

TcpClient c;

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

...我怎样才能首先检查我的机器上某个端口是否空闲?

我的意思是它没有被任何其他应用程序使用.如果某个应用程序正在使用某个端口,则其他应用程序无法使用它 - 阿里

你误解了这里发生的事情.

TcpClient(...)参数是您希望连接的服务器IP和服务器端口.

TcpClient从可用池中选择一个临时本地端口以与服务器通信.无需检查本地端口的可用性,因为winsock层会自动处理.

如果您无法使用上述代码片段连接到服务器,则问题可能是多个问题中的一个或多个.(即服务器IP和/或端口错误,远程服务器不可用等等.)


Mel*_*are 15

谢谢你的提示.我需要相同的功能,但在服务器端检查端口是否正在使用,所以我将其修改为此代码.

 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;
}
Run Code Online (Sandbox Code Playgroud)


Sim*_*one 7

从可用端口中我会排除:

  • 活动 TCP 连接
  • 活动 TCP 侦听器
  • 活动 UDP 侦听器

通过以下导入:

using System.Net.NetworkInformation;
Run Code Online (Sandbox Code Playgroud)

您可以使用以下函数来检查端口是否可用:

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

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

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

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

    foreach (int p in availablePorts){
        if (p == myPort) return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

我为那些使用VB.NET的人提供了类似的功能:

using System.Net.NetworkInformation;
Run Code Online (Sandbox Code Playgroud)


CCo*_*ron 7

为了回答在 dotnet core 3.1 中寻找自由端口(这是我在单元测试中需要的)的确切问题,我提出了这个

public static int GetAvailablePort(IPAddress ip) {
        TcpListener l = new TcpListener(ip, 0);
        l.Start();
        int port = ((IPEndPoint)l.LocalEndpoint).Port;
        l.Stop();
        Log.Info($"Available port found: {port}");
        return port;
    }
Run Code Online (Sandbox Code Playgroud)

注意:基于@user207421关于端口零的评论,我搜索并找到了这个并对其进行了稍微修改。


小智 6

谢谢你的答案.我不得不调整它以供我使用.我需要检查是否正在监听端口,而不是必须激活.为此,我换了

TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
Run Code Online (Sandbox Code Playgroud)

IPEndPoint[] objEndPoints = ipGlobalProperties.GetActiveTcpListeners();.  
Run Code Online (Sandbox Code Playgroud)

我迭代了端点数组,检查我的端口值是否找不到.


Lea*_*ing 5

string hostname = "localhost";
int portno = 9081;
IPAddress ipa = (IPAddress) Dns.GetHostAddresses(hostname)[0];


try
{
    System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
    sock.Connect(ipa, portno);
    if (sock.Connected == true)  // Port is in use and connection is successful
            MessageBox.Show("Port is Closed");
    sock.Close();

}
catch (System.Net.Sockets.SocketException ex)
{
    if (ex.ErrorCode == 10061)  // Port is unused and could not establish connection 
        MessageBox.Show("Port is Open!");
    else
        MessageBox.Show(ex.Message);
}
Run Code Online (Sandbox Code Playgroud)