【问题标题】:How to remove mentioned characters from network stream string如何从网络流字符串中删除提到的字符
【发布时间】:2016-10-26 18:26:21
【问题描述】:

我正在使用 TcpClient 从网页进行 telnet

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;

但字符串中包含以下字符。如何删除或替换以在 Web 表单中以可读格式显示 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;9f[4;37f;11f[4;34f;40f[4;37f;40f[4;34f;40f”

【问题讨论】:

    标签: c# html webforms telnet tcpclient


    【解决方案1】:

    问题是您的 telnet 服务器假定您支持ANSI/VT100。因为这就是所有这些角色。例如(&lt;ESC&gt; 表示带有ascii value 27 的字符)

    &lt;ESC&gt;[4;34f

    是强制光标位置&lt;ESC&gt;[{ROW};{COLUMN}f的ANSI控制序列。

    您要么必须说服 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 来读取网络流。 StreamReader 在其构造函数中带有一个接受编码的重载。这可以防止您必须自己处理流中的解码字节,这在您的代码中肯定被破坏了。您无法安全地解码部分字节缓冲区。

    【讨论】:

      猜你喜欢
      • 2013-10-06
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多