В C # как проверить, доступен ли порт TCP? - PullRequest
111 голосов
/ 20 февраля 2009

В C # для использования TcpClient или вообще для подключения к сокету, как я могу сначала проверить, свободен ли определенный порт на моей машине?

подробнее: Это код, который я использую:

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

Ответы [ 18 ]

2 голосов
/ 20 февраля 2009

Вы говорите

Я имею в виду, что он не используется ни одним другое приложение. Если приложение использует порт, который другие не могут использовать пока не станет свободным.

Но вы всегда можете подключиться к порту, когда другие его используют, если что-то там слушает. В противном случае http-порт 80 был бы беспорядком.

Если ваш

   c = new TcpClient(ip, port);

терпит неудачу, тогда ничего не слушает там. В противном случае он подключится, даже если на каком-либо другом компьютере / приложении есть сокет, открытый для этого ip и порта.

1 голос
/ 09 апреля 2009

Имейте в виду, что временной интервал между проверкой и моментом установления соединения каким-либо процессом может занять порт - классический TOCTOU . Почему бы вам просто не попробовать подключиться? Если произойдет сбой, вы знаете, что порт недоступен.

1 голос
/ 17 апреля 2015
    public static bool TestOpenPort(int Port)
    {
        var tcpListener = default(TcpListener);

        try
        {
            var ipAddress = Dns.GetHostEntry("localhost").AddressList[0];

            tcpListener = new TcpListener(ipAddress, Port);
            tcpListener.Start();

            return true;
        }
        catch (SocketException)
        {
        }
        finally
        {
            if (tcpListener != null)
                tcpListener.Stop();
        }

        return false;
    }
1 голос
/ 09 апреля 2009

Вам не нужно знать, какие порты открыты на вашем локальном компьютере для подключения к какой-либо удаленной службе TCP (если вы не хотите использовать определенный локальный порт, но обычно это не так).

Каждое соединение TCP / IP идентифицируется 4 значениями: удаленный IP, номер удаленного порта, локальный IP, номер локального порта, но вам нужно знать только удаленный IP и номер удаленного порта, чтобы установить соединение.

Когда вы создаете TCP-соединение, используя

TcpClient c;
c = new TcpClient(remote_ip, remote_port);

Ваша система автоматически назначит вашему соединению один из многих свободных номеров локальных портов. Вам не нужно ничего делать. Вы также можете проверить, открыт ли удаленный порт. но нет лучшего способа сделать это, чем просто попытаться подключиться к нему.

1 голос
/ 10 июля 2018

Из доступных портов я бы исключил:

  • активные TCP-соединения
  • активных слушателей TCP
  • активных слушателей UDP

Со следующим импортом:

using System.Net.NetworkInformation;

Вы можете использовать следующую функцию, чтобы проверить, доступен порт или нет:

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;
}

Я даю вам аналогичную функцию для тех, кто использует 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
0 голосов
/ 03 декабря 2018

Проверьте код ошибки 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;
}
0 голосов
/ 06 мая 2016

попробуйте это, в моем случае номер порта для созданного объекта был недоступен, поэтому я придумал это

IPEndPoint endPoint;
int port = 1;
while (true)
{
    try
    {
        endPoint = new IPEndPoint(IPAddress.Any, port);
        break;
    }
    catch (SocketException)
    {
         port++;
    }
}
0 голосов
/ 08 января 2016
test_connection("ip", port);


public void test_connection(String hostname, int portno) {
  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) {
     MessageBox.Show("Port is in use");
   }

   sock.Close();
 }
 catch (System.Net.Sockets.SocketException ex) {
   if (ex.ErrorCode == 10060) {
     MessageBox.Show("No connection.");
   }
 }
}
...