Esempio n. 1
0
        /// <summary>
        /// 处理Telnet命令并返回数据
        /// </summary>
        /// <param name="recv"></param>
        /// <param name="send"></param>
        /// <param name="data"></param>
        void ParseTelnetCommand(RingQueue <byte> recv, RingQueue <byte> send, RingQueue <byte> data)
        {
            while (recv.Count > 0 && data.Available > 0)
            {
                var b = recv.Shift();

                if (b == IAC)
                {
                    //命令处理
                    if (recv.Count < 2)
                    {
                        recv.Unshift(b);
                        break;
                    }

                    var action = recv.Shift();
                    var option = recv.Shift();

                    switch (option)
                    {
                    case ECHO:
                    case NOGA:
                    case TERMTYPE:
                    case NAWS:
                        switch (action)
                        {
                        case WILL:
                            send.PushValues(new byte[] { IAC, DO, option });
                            break;

                        case DO:
                            send.PushValues(new byte[] { IAC, WILL, option });
                            break;

                        case SB:
                            switch (option)
                            {
                            case TERMTYPE:
                                if (recv.Count < 3)
                                {
                                    recv.UnshiftValues(new byte[] { option, action, b });
                                    break;
                                }
                                if (recv.Shift() == 1)
                                {
                                    recv.Shift(); recv.Shift();
                                    //发送客户端型号
                                    send.PushValues(new byte[] { IAC, SB, TERMTYPE, 0 });
                                    send.PushValues(Encoding.Default.GetBytes(TermType));
                                    send.PushValues(new byte[] { IAC, SE });
                                }
                                break;
                            }
                            break;
                        }
                        if (action == WILL && option == NAWS)
                        {
                            //发送窗体大小
                            send.PushValues(new byte[] { IAC, SB, NAWS,
                                                         (byte)((ScreenColumns >> 8) & 0xFF), (byte)(ScreenColumns & 0xFF),
                                                         (byte)((ScreenRows >> 8) & 0xFF), (byte)(ScreenRows & 0xFF), IAC, SE });
                        }
                        break;

                    default:
                        //拒绝其他一切选项
                        switch (action)
                        {
                        case WILL:
                        case WONT:
                            send.PushValues(new byte[] { IAC, DONT, option });
                            break;

                        case DO:
                        case DONT:
                            send.PushValues(new byte[] { IAC, WONT, option });
                            break;
                        }
                        break;
                    }
                }
                else
                {
                    //丢给VT220解析器
                    data.Push(b);
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// 进入消息等待
        /// </summary>
        public void Process()
        {
            //用户发送队列
            m_userQueue = new RingQueue <byte>(1024);
            //vt220待解析数据
            m_telnetDataQueue = new RingQueue <byte>(8192);
            //消息处理
            new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
            {
                //接收缓存队列
                var recvQueue = new RingQueue <byte>(8192);

                //发送缓存队列
                var sendQueue = new RingQueue <byte>(1024);

                var io         = m_conn.GetStream();
                var sendStream = new System.IO.BufferedStream(io);
                var recvStream = new System.IO.BufferedStream(io);

                while (m_conn != null && m_conn.Connected)
                {
                    //接收服务端数据
                    while (io.DataAvailable && recvQueue.Available > 0)
                    {
                        var b = io.ReadByte();
                        if (b == -1)
                        {
                            break;
                        }
                        recvQueue.Push((byte)b);
                    }
                    //解析Telnet协议 并 响应服务器
                    ParseTelnetCommand(recvQueue, sendQueue, m_telnetDataQueue);

                    //解析VT220协议
                    ParseVT220Command(m_telnetDataQueue);

                    //客户端发送数据
                    while (sendQueue.Count > 0 && m_conn.Connected)
                    {
                        var data = sendQueue.ToArray();
                        sendStream.Write(data, 0, data.Length);
                        sendStream.Flush();
                        sendQueue.Clear();
                    }

                    //发送用户数据
                    while (m_userQueue.Count > 0 && m_conn.Connected)
                    {
                        var data = m_userQueue.ToArray();
                        sendStream.Write(data, 0, data.Length);
                        sendStream.Flush();
                        m_userQueue.Clear();
                    }

                    //休眠100ms(文件输出时20ms)
                    System.Threading.Thread.Sleep(IsPrinting?10:100);

                    //检测终止标志(不确定)
                    if (m_conn != null && m_conn.Client.Poll(1, SelectMode.SelectRead) && m_conn.Client.Available == 0)
                    {
                        this.Disconnect();
                        Logger.Info("Telnet 连接关闭(收到服务端指令)");
                    }
                }
            })).Start();

            //绑定控件
            //绑定用户输入事件
            Screen.KeyPress += new System.Windows.Forms.KeyPressEventHandler(delegate(object sender, System.Windows.Forms.KeyPressEventArgs e)
            {
                m_userQueue.Push(Convert.ToByte(e.KeyChar));
            });

            Screen.KeyDown += new System.Windows.Forms.KeyEventHandler(delegate(object sender, System.Windows.Forms.KeyEventArgs e)
            {
                SendKey(e.KeyCode);
                //Console.WriteLine(e.KeyCode);
            });
            //绑定用户输入事件
        }