2016-06-24 4 views
2

ich tue Telnet von einer Web-Seite mit TcpClientWie die oben genannte Zeichen von Netzwerk-Stream-String

server = new TcpClient(ConfigurationManager.AppSettings["DynamicIP"], Convert.ToInt32(ConfigurationManager.AppSettings["DynamicPort"])); 
      ns = server.GetStream(); 

zu entfernen, während Reaktion eines Stroms mit folgenden Verfahren zu lesen.

if (ns.CanRead) 
     { 
      byte[] readBuffer = new byte[1024]; 
      int numBytesRead = 0; 
      do 
      { 
       numBytesRead = ns.Read(readBuffer, 0, readBuffer.Length); 
       // ss= Encoding.GetEncoding(1252).GetString(readBuffer.ToArray()); 
       //sb.Append(readBuffer[0].ToString); 
       sb.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numBytesRead)); 
       sb.Replace(Convert.ToChar(24), ' '); 
       sb.Replace(Convert.ToChar(255), ' '); 
       sb.Replace('?', ' '); 
       //sb.Replace(Environment.NewLine, "<br />").ToString(); 
      } 
      while (ns.DataAvailable); 
     } 
     // var s = Regex.Replace(sb.ToString(), @"[^\u0000-\u007F]", string.Empty); 
     //var s = "<br/>" + sb.ToString(); 
     //s = s.Normalize(NormalizationForm.FormD); 
     //var chars = s.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark).ToArray(); 
     //return new string(chars).Normalize(NormalizationForm.FormC); 
     ////return "<br/>" + s.ToString(); 
     var dd = "<br/>" + sb.ToString(); 
     return dd; 

aber Zeichenfolge enthält die folgenden Zeichen darin. Wie zu entfernen oder zu ersetzen, um die Telnet-Antwort in lesbarem Format im Web-Formular anzuzeigen? Ich habe so viele Dinge versucht, aber vergebens.

Ich möchte die Antwort in der Webseite genau wie Putty die Antwort lesen.

Vielen Dank im Voraus.

; 40f; 9f; 40f; 9f; 40f; 2f; 40f; 9f [4; 34f; 9f [4; 37f; 2f [4; 34f; 9f [4; 34f; 11f; 40f; 9f 40f; 9f; 40f; 11f [4; 39f; 9f [4; 34f; 11f [4; 37f; 9f [4; 34f; 9f [4; 37f; 40f [4; 34f; 40f; 9f; 40f; 11f 40f; 11f; 40f; 9f [4; 37f; 9f [4; 37f; 9f [4; 37f; 11f [4; 34f; 9f [4; 34f; 40f [4; 34f; 40f; 11f; 40f; 11f 40f; 11f; 40f; 9f [4; 39f; 2f [4; 34f; 9f [4; 37f; 9f [4; 34f; 40f [4; 37f; 40f; 9f; 40f; 9f; 40f; 9f; 40f 11f [4; 37f; 9f [4; 37f; 11f [4; 37f; 9f [4; 34f; 40f [4; 37f; 40f [4; 37f; 40f; 9f; 40f; 2f; 40f; 9f [4 ; 37f; 9f [4; 37f; 11f [4; 37f; 11f [4; 39f; 9f [4; 37f; 40f; 9f; 40f; 9f; 40f; 11f; 40f; 9f; 40f; 9f [4; 34f ; 2f [4; 34f; 9f [4; 37f; 11f [4; 34f; 40f [4; 37f; 40f [4; 34f; 40f“

Antwort

1

Das Problem ist, dass Ihr Telnet-Server vorausgesetzt, dass Sie ANSI/VT100 unterstützen Bec Das sind alle diese Charaktere. Zum Beispiel (<ESC> gibt die charater mit ascii value 27)

<ESC>[4;34f

ist die ANSI-Steuersequenz für Force-Cursor-Position <ESC>[{ROW};{COLUMN}f.

Sie müssen entweder Ihren Telnet-Server davon überzeugen, dass Sie ANSI/VT100 nicht unterstützen, oder einen Parser schreiben, der die ANSI/VT100-Steuercodes verarbeiten kann.

Für jetzt tat ich letzteres. Ein naives Parser könnte so aussehen. Es macht nichts, außer das Analysieren der ANSI/VT100-Codes und hängt diese nicht an den StringBuilder an.

var ns = server.GetStream(); 
// keep state of the parser 
bool Ansi = false; 
bool AnsiSub = false; 
bool InFirstNumber = false; 
bool InSecondNumber = false; 
string firstnumber = String.Empty; 
string secondnumber = String.Empty; 

if (ns.CanRead) 
{ 
    // testcase 
    // var ms = new MemoryStream(Encoding.ASCII.GetBytes("foo\x1b[123A\x1b[123;456ftest2\x1bKblah\x1b[s")); 
    var sr = new StreamReader(ns, Encoding.ASCII); 
    while(!sr.EndOfStream) 
    { 
     var chr = sr.Read(); 
     switch (chr) 
     { 
      case 27: 
       // escape char means next chars will be ANSI code 
       Ansi = true; 
       break; 
      default: 
       if (Ansi) 
       { 
        // will this be a single ANSI code char or multiple 
        if (!AnsiSub) 
        { 
         switch ((char)chr) 
         { 
          case '[': 
           // multiple, set state 
           AnsiSub = true; 
           InFirstNumber = true; 
           InSecondNumber = false; 
           firstnumber = string.Empty; 
           secondnumber = string.Empty; 
           break; 
          default: 
           // handle this char if needed 
           // possible is: 78()DMH 
           Ansi = false; 
           AnsiSub = false; 
           break; 
         } 
        } 
        else 
        { 
         var achar = (char)chr; 
         // number checks and capturing 
         if (Char.IsDigit(achar)) 
         { 
          // a bit sloppy 
          if (InFirstNumber) 
          { 
           firstnumber += achar; 
          } 
          else 
          { 
           // HACK, refactor later 
           if (InSecondNumber) 
           { 
            secondnumber += achar; 
           } 
          } 
         } 
         else 
         { 
          if (achar == ';') 
          { 
           // number sequence break 
           InSecondNumber = true; 
           InFirstNumber = false; 
          } 
          else 
          { 
           // last char of ANSI code 
           switch (achar) 
           { 
            case 'A': 
             // Cursor Up  <ESC>[{COUNT}A 
             break; 
            case 'f': 
             // Force Cursor Position <ESC>[{ROW};{COLUMN}f 
             Console.WriteLine("Force cursor row:{0}, col:{1}", firstnumber, secondnumber); 
             break; 
           } 
           // now we are done, reset state 
           Ansi = false; 
           AnsiSub = false; 
          } 
         } 
        } 
       } 
       else 
       { 
        // plain character 
        sb.Append((Char)chr); 
       } 
       break; 
     } 
    } 

Beachten Sie, dass ich ein StreamReader verwendet, um das Network zu lesen. StreamReader kommt in seinem Konstruktor mit einer Überladung, die eine Codierung akzeptiert. Das verhindert, dass Sie sich selbst mit dem Decodieren von Bytes aus dem Stream beschäftigen müssen, was definitiv in Ihrem Code fehlgeschlagen ist. Teilbybuffer können nicht sicher decodiert werden.