telnet 协商中的杂散数据字节。它来自哪里?

Posted

技术标签:

【中文标题】telnet 协商中的杂散数据字节。它来自哪里?【英文标题】:Stray data byte in telnet negotiation. Where is it coming from? 【发布时间】:2011-12-14 15:29:57 【问题描述】:

我正在使用简约的 telnet 通过表单项目来支持 telnet 客户端。我发现在协商过程中,客户端向服务器发送了 37 个数据字节。如果那是 IAC,它将用于身份验证。在客户端和服务器之间完成协商之前,不应发送任何数据。

我被困住了。有人可以帮我弄清楚为什么这个东西会自动发送 37 个数据字节吗?这是我在使用wireshark 嗅探数据包时发现的。 Void Parsetelnet 部分是传输发生的地方。

使用 Wireshark,我没有看到服务器实例要求身份验证选项。所以我不知道班级从哪里获得字节 37。我需要它不发送那个。 这里是类

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;

    namespace STC_Control
    
        enum Verbs
        
            WILL = 251,
            WONT = 252,
            DO = 253,
            DONT = 254,
            IAC = 255
        

        enum Options
        
            SGA = 3
        

        class TelnetConnection
        
            TcpClient tcpSocket;

            int TimeOutMs = 100;

            public TelnetConnection(string Hostname, int Port)
            
                tcpSocket = new TcpClient(Hostname, Port);

            

            public void WriteLine(string cmd)
            
                Write(cmd + "\n");
            

            public void Write(string cmd)
            
                if (!tcpSocket.Connected) return;
                byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
                tcpSocket.GetStream().Write(buf, 0, buf.Length);
            

            public string Read()
            

                if (!tcpSocket.Connected) return null;

                    StringBuilder sb = new StringBuilder();

                    do
                    
                        ParseTelnet(sb);
                        System.Threading.Thread.Sleep(TimeOutMs);
                     while (tcpSocket.Available > 0);
                    return sb.ToString();

            

            public bool IsConnected
            
                get  return tcpSocket.Connected; 
            

            void ParseTelnet(StringBuilder sb)
            
                while (tcpSocket.Available > 0)
                
                    int input = tcpSocket.GetStream().ReadByte();
                    switch (input)
                    
                        case -1:
                            break;
                        case (int)Verbs.IAC:
                            // interpret as command
                            int inputverb = tcpSocket.GetStream().ReadByte();
                            if (inputverb == -1) break;
                            switch (inputverb)
                            
                                case (int)Verbs.IAC:
                                    //literal IAC = 255 escaped, so append char 255 to string
                                    sb.Append(inputverb);
                                    break;
                                case (int)Verbs.DO:
                                case (int)Verbs.DONT:
                                case (int)Verbs.WILL:
                                case (int)Verbs.WONT:
                                    // reply to all commands with "WONT", unless it is SGA (suppres go ahead)
                                    int inputoption = tcpSocket.GetStream().ReadByte();
                                    if (inputoption == -1) break;
                                    tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
                                    if (inputoption == (int)Options.SGA)
                                        tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);
                                    else
                                        tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
                                    tcpSocket.GetStream().WriteByte((byte)inputoption);
                                    break;
                                default:
                                    break;
                            
                            break;
                        default:
                            sb.Append((char)input);
                            break;
                    
                

            
        
    

【问题讨论】:

【参考方案1】:

Telnet Authentication Option“将 Telnet 协议的身份验证选项指定为协商身份验证类型和模式的通用方法,包括是否应使用加密以及是否应转发凭据。” source

MSDN 上有一个example,描述了 Telnet 上的 NTLM 身份验证会话。

【讨论】:

以上是关于telnet 协商中的杂散数据字节。它来自哪里?的主要内容,如果未能解决你的问题,请参考以下文章

在 snprintf 的输出中看到的杂散字符

Ajax 响应中的杂散字符?

调试节点集群中的杂散未捕获异常 (ECONNRESET)

string中的杂散知识点

抓包分析Telnet远程登陆协议信令交互过程

音频数据有问题