2016-12-18 3 views
0

Я создаю клиентское приложение на C# для отправки команд через telnet-протокол на удаленный маршрутизатор. В настоящее время удаленный маршрутизатор закрывает незанятые соединения в течение 2-5 минут. Я ищу способ сохранить свою связь. Я попытался следующий код:C# tcp socket keepalive

socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 

, но он не работает.

Вот мой код TelnetClient:

public class TelnetClient 
{ 
    private NetworkStream ns; 
    private Socket client; 
    private const string prompt = ">"; 
    private const int buffer = 2048; 
    private string host; 
    private int port; 
    private string user; 
    private string password; 

    public TelnetClient(string host, int port, string user, string password) 
    { 
     client = new Socket(SocketType.Stream, ProtocolType.Tcp); 

     client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true); 
     this.host = host; 
     this.port = port; 
     this.user = user; 
     this.password = password; 
    } 


    public bool Connect() 
    { 
     try 
     { 
      client.Connect(host, port); 
      ns = new NetworkStream(client); 

      return true; 
     } 
     catch (Exception e) 
     { 
      Trace.TraceError(e.Message); 

      return false; 
     } 
    } 

    public bool Login() 
    { 
     Write(this.user); 
     ReadUntil(":", 1000); 
     Write(this.password); 
     if(ReadUntil(">", 1000) != null) 
      return true; 
     return false; 
    } 

    public string ReadUntil(string pattern, long timeout) 
    { 
     StringBuilder sb = new StringBuilder(); 
     string text = ""; 
     byte[] arr = new byte[buffer]; 

     try 
     { 
      if (ns.CanRead) 
      { 
       Stopwatch s = new Stopwatch(); 
       s.Start(); 
       while (s.Elapsed < TimeSpan.FromMilliseconds(timeout)) 
       { 
        text = sb.ToString().Trim().ToLower(); 

        if (pattern.Length > 0 && text.ToLower().Trim().EndsWith(pattern)) 
        { 
         return text.ToLower(); 
        } 

        if (ns.DataAvailable) 
        { 
         int count = ns.Read(arr, 0, arr.Length); 
         sb.AppendFormat("{0}", Encoding.ASCII.GetString(arr, 0, count)); 
        } 
       } 
      } 
      else 
       return null; 
     } 
     catch (Exception ex) 
     { 
      Trace.TraceError(ex.Message); 
     } 
     return null; 
    } 

    public void Write(string value) 
    { 
     byte[] arr = Encoding.ASCII.GetBytes(value + Environment.NewLine); 



     try 
     { 
      ns.Write(arr, 0, arr.Length); 
      ns.Flush(); 
      System.Threading.Thread.Sleep(1000); 
     } 
     catch (Exception e) 
     { 
      Trace.TraceError(e.Message); 
     } 
    } 

    public string SendCommand(string cmd, int timeout) 
    { 
     Write(cmd); 
     return ReadUntil(prompt, timeout); 
    } 

    public void Disconnect() 
    { 
     try 
     { 
      byte[] arr = Encoding.ASCII.GetBytes("exit" + Environment.NewLine); 
      ns.Write(arr, 0, arr.Length); 
      ns.Close(); 
      client.Close(); 
     } 
     catch (Exception e) 
     { 
      Trace.TraceError(e.Message); 
     } 
    } 
} 
+0

Что не работает? У вас есть сообщение об ошибке? Каково поведение вашего скрипта? Нам нужна дополнительная информация, чтобы помочь вам (больше кода, ошибок, ...) –

+0

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

+0

Возможный дубликат [Tcp connection Keep alive] (http://stackoverflow.com/questions/18488562/tcp-connection-keep-alive) –

ответ

0

На одном из продуктов моей команды, мы обнаружили, что TCP поддержания активности интервал не был уволен достаточно часто достаточно, чтобы порт маршрутизатора открыт для некоторых NATs ,

Мы обновили протокол, чтобы отправить сообщение «ping», на которое ответил «понг» каждые 45 секунд. Но это было для протокола, который мы контролировали.

Для telnet лучшим вариантом было бы отправить символ выхода telnet, за которым следует команда telnet для NOP (241) или AYT (246) на каждом интервале. См. RFC 854 для более подробной информации.

Смежные вопросы