如何从网络流字符串中删除提到的字符

时间:2016-06-24 07:47:49

标签: c# html webforms telnet tcpclient

我正在使用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;

但字符串中包含以下字符。如何删除或替换以便以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“

1 个答案:

答案 0 :(得分:1)

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

  

<ESC>[4;34f

是强制光标位置<ESC>[{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在其构造函数中带有一个重载,它接受一个Encoding。这可以防止您必须自己处理流中的字节解码,这在您的代码中肯定会被破坏。您无法安全地解码部分字节缓冲区。