2010-05-14 3 views
3

Мне нужно опросить сервер, на котором запущено какое-то проприетарное программное обеспечение, чтобы определить, работает ли эта служба. Используя wirehark, я смог сузить используемый порт TCP, но кажется, что трафик зашифрован.Определить, прослушивает ли сервер данный порт

В моем случае его безопасная ставка заключается в том, что если сервер принимает соединения (т. Е. Telnet serverName 1234), обслуживание завершается, и все в порядке. Другими словами, мне не нужен фактический обмен данными, просто откройте соединение и затем безопасно закройте его.

Мне интересно, как я могу эмулировать это с помощью C# и Sockets. Мое сетевое программирование в основном заканчивается WebClient, поэтому любая помощь здесь очень ценится.

ответ

6

Процесс на самом деле очень прост.

using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) 
{ 
    try 
    { 
     socket.Connect(host, port); 
    } 
    catch (SocketException ex) 
    { 
     if (ex.SocketErrorCode == SocketError.ConnectionRefused) 
     { 
      // ... 
     } 
    } 
} 
+0

Есть ли способ настроить таймаут соединения? Кажется, что он терпит неудачу, но только через минуту ... – Nate

+0

@Nate Я считаю, что именно так длится процесс. Опция тайм-аута подключения отсутствует. – ChaosPandion

+0

Я добавил 'if (ex.SocketErrorCode == SocketError.ConnectionRefused || ex.SocketErrorCode == SocketError.TimedOut)' – Nate

0

Используйте класс TcpClient для подключения сервера.

3

Просто используйте TcpClient попытайтесь подключиться к серверу, TcpClient.Connect будет генерировать исключение, если соединение завершится с ошибкой.

bool IsListening(string server, int port) 
{ 
    using(TcpClient client = new TcpClient()) 
    { 
     try 
     { 
      client.Connect(server, port); 
     } 
     catch(SocketException) 
     { 
      return false; 
     } 
     client.Close(); 
     return true; 
    } 
} 
+0

Есть ли способ настроить таймаут соединения? Кажется, что он не работает, но только через минуту ... – Nate

2

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

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

public static bool IsServerUp(string server, int port, int timeout) 
    { 
     bool isUp; 

     try 
     { 
      using (TcpClient tcp = new TcpClient()) 
      { 
       IAsyncResult ar = tcp.BeginConnect(server, port, null, null); 
       WaitHandle wh = ar.AsyncWaitHandle; 

       try 
       { 
        if (!wh.WaitOne(TimeSpan.FromMilliseconds(timeout), false)) 
        { 
         tcp.EndConnect(ar); 
         tcp.Close(); 
         throw new SocketException(); 
        } 

        isUp = true; 
        tcp.EndConnect(ar); 
       } 
       finally 
       { 
        wh.Close(); 
       } 
      } 
     } 
     catch (SocketException e) 
     { 
      LOGGER.Warn(string.Format("TCP connection to server {0} failed.", server), e); 
      isUp = false; 
     } 

     return isUp; 
Смежные вопросы