2016-12-18 1 views
0

텔넷 프로토콜을 통해 원격 라우터에 명령을 보내는 클라이언트 응용 프로그램을 C#에서 만들고 있습니다. 현재 원격 라우터는 유휴 연결을 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 연결 유지] (http://stackoverflow.com/questions/18488562/tcp-connection-keep-alive)의 가능한 복제본 –

답변

0

, 우리는 TCP가 연결 유지 간격이 특정 NAT를 열어 라우터 포트를 유지하기 위해 충분히 자주 발사되지 않았다 발견 .

45 초마다 "pong"으로 응답 한 "ping"메시지를 보내도록 프로토콜을 업데이트했습니다. 그러나 그것은 우리가 통제 한 의정서를위한 것이 었습니다.

텔넷의 경우 모든 간격마다 텔넷 이스케이프 문자 다음에 NOP (241) 또는 AYT (246)의 텔넷 명령을 보내는 것이 가장 좋습니다. 자세한 내용은 RFC 854를 참조하십시오.