2016-06-24 1 views
2

Я делаю телнет с веб-страницы с помощью TcpClientКак удалить символы из упомянутых сетевого потока строки

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

При чтении реакции потока с описанным ниже методом.

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; 

но строка содержит следующие символы в ней. Как удалить или заменить, чтобы показать ответ telnet в читаемом формате в веб-форме? Я пробовал так много всего, но напрасно.

Я хотел бы показать ответ на веб-странице так же, как Putty читает ответ.

Заранее спасибо.

; 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, 9е [4, 37f, 11f [4, 34f, 40f [4, 37f, 40f [4, 34f, 40f»

ответ

1

проблема заключается в том, что ваш сервер Telnet предполагает, что вы поддерживать ANSI/VT100 Bec ause - вот что представляют собой все эти персонажи. Например (<ESC> указывает на charater с ascii value 27)

<ESC>[4;34f

является управляющей последовательности ANSI для Force позиции курсора <ESC>[{ROW};{COLUMN}f.

Вам либо нужно убедить ваш сервер telnet, что вы не поддерживаете ANSI/VT100, либо напишите парсер, который может обрабатывать управляющие коды ANSI/VT100.

На данный момент я сделал последнее. Наивный парсер может выглядеть так. Он ничего не делает, кроме разбора кодов ANSI/VT100 и не добавляет их в StringBuilder.

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

Обратите внимание, что я использовал StreamReader читать NetworkStream. StreamReader поставляется с перегрузкой в ​​своем конструкторе, который принимает кодировку. Это препятствует тому, что вам приходится иметь дело с декодированием байтов из потока самостоятельно, что было определенно нарушено в вашем коде. Вы не можете безопасно декодировать частичные байтовые буферы.