C# 实现Telnet

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

namespace BLL
{
    public class TelnetClient
    {
        private TcpClient Client;
        private NetworkStream ns;
        private string m_LogonPrompt = "ogin:";
        private string m_PasswordPrompt = "assword:";
        private readonly int BuffSize = 1024 * 4;

        /// <summary>       
        /// 登录输入用户名提示字符       
        /// 默认值:ogin:       
        /// </summary>       
        public string LoginPrompt       
        {           
            set { m_LogonPrompt = value; }           
            get { return m_LogonPrompt; }       
        }
        /// <summary>       
        /// 登录输入密码提示字符       
        /// 默认值:assword:       
        /// </summary>    
        public string PasswordPrompt       
        {           
            set { m_PasswordPrompt = value; }           
            get { return m_PasswordPrompt; }       
        }
        /// <summary>       
        /// 连接状态       
        /// </summary>       
        public bool Connected       
        {           
            get { return Client != null ? Client.Connected : false; }       
        }
        /// <summary>       
        /// 连接远端主机       
        /// </summary>       
        /// <param name="hostname">主机名称</param>       
        /// <param name="port">端口</param>       
        /// <returns>远端主机响应文本</returns>       
        public string Connect(string hostname, int port)       
        {           
            string result = string.Empty;           
            try           
            {               
                Client = new TcpClient(hostname, port);               
                ns = Client.GetStream();               
                result = Negotiate();           
            }           
            catch (Exception e)           
            {               
                result = e.Message;           
            }           
            return result;       
        }
        /// <summary>       
        /// 连接远端主机并登录       
        /// </summary>       
        /// <param name="hostname">主机名称</param>       
        /// <param name="port">端口</param>       
        /// <param name="username">用户名</param>       
        /// <param name="password">密码</param>       
        /// <param name="waitTime">连接等待时间</param>       
        /// <returns></returns>       
        public string Connect(string hostname, int port, string username, string password, int waitTime)       
        {           
            string result = string.Empty;           
            result = Connect(hostname, port);           
            if (Connected && result.EndsWith(LoginPrompt))           
            {               
                Send(username, waitTime);               
                result = Receive();               
                if (result.EndsWith(PasswordPrompt))               
                {                   
                    Send(password, waitTime);                   
                    result = Receive();                   
                    if (!result.EndsWith("<"))                   
                    {                       
                        Client.Close();                       
                        result = "Logon Error";                   
                    }               
                }           
            }           
            return result;       
        }
        /// <summary>       
        /// 接收       
        /// </summary>       
        /// <returns>传回的数据</returns>       
        public string Receive()       
        {           
            StringBuilder result = new StringBuilder();           
            if (Connected && ns.CanRead)           
            {               
                byte[] buff = new byte[BuffSize];               
                int numberOfRead = 0;               
                do               
                {                   
                    numberOfRead = ns.Read(buff, 0, BuffSize);                   
                    result.AppendFormat("{0}", Encoding.ASCII.GetString(buff, 0, numberOfRead));               
                }
                while (ns.DataAvailable);           
            }           
            return result.ToString().Trim();       
        }
        /// <summary>       
        /// 发送       
        /// </summary>       
        /// <param name="cmd">指令</param>       
        /// <param name="waitTime">等待超时时间(毫秒)</param>       
        public void Send(string cmd, int waitTime)
        {           
            if (Connected && ns.CanWrite)           
            {               
                cmd += "\r\n";               
                byte[] buff = Encoding.ASCII.GetBytes(cmd);               
                ns.Write(buff, 0, buff.Length);               
                System.Threading.Thread.Sleep(waitTime);           
            }       
        }
         /// <summary>       
        /// 关闭       
        /// </summary>       
        public void Close()       
        {           
            Client.Close();       
        }
        /// <summary>       
        /// 处理Telnet选项谈判,直到出现用户名输入提示       
        /// </summary>       
        /// <returns></returns>       
        private string Negotiate()       
        {           
            string result = string.Empty;           
            if (Connected)           
            {               
                while (true)               
                {                   
                    byte[] rev = ReceiveBytes();                   
                    result = Encoding.ASCII.GetString(rev).Trim();                   
                    if (result.EndsWith(LoginPrompt))                   
                    {                       
                        break;                   
                    }                   
                    int count = rev.Length / 3;                   
                    for (int i = 0; i < count; i++)                   
                    {                       
                        int iac = rev[i * 3];                       
                        int cmd = rev[i * 3 + 1];                       
                        int value = rev[i * 3 + 2];                       
                        if (((int)Verbs.IAC) != iac)                       
                        {                           
                            continue;                       
                        }                       
                        switch (cmd)                       
                        {                           
                            case (int)Verbs.DO:                               
                                ns.WriteByte((byte)iac);                               
                                ns.WriteByte(value == (int)Options.RD ? (byte)Verbs.WILL : (byte)Verbs.WONT);                               
                                ns.WriteByte((byte)value);                               
                                break;                           
                            case (int)Verbs.DONT:                               
                                ns.WriteByte((byte)iac);                               
                                ns.WriteByte((byte)Verbs.WONT);                               
                                ns.WriteByte((byte)value);                               
                                break;                           
                            case (int)Verbs.WILL:                               
                                ns.WriteByte((byte)iac);                               
                                ns.WriteByte(value == (int)Options.SGA ? (byte)Verbs.DO : (byte)Verbs.DONT);                               
                                ns.WriteByte((byte)value);                               
                                break;                           
                            case (int)Verbs.WONT:                               
                                ns.WriteByte((byte)iac);                               
                                ns.WriteByte((byte)Verbs.DONT);                               
                                ns.WriteByte((byte)value);                               
                                break;                           
                            default:                               
                                break;                       
                        }                   
                    }               
                }           
            }           
            return result;       
        }
        /// <summary>       
        /// 读取字节流       
        /// </summary>       
        /// <returns></returns>       
        private byte[] ReceiveBytes()       
        {           
            byte[] result = new byte[0];           
            byte[] buff = new byte[BuffSize];           
            int numberOfRead = 0;           
            if (Connected && ns.CanRead)           
            {               
                numberOfRead = ns.Read(buff, 0, BuffSize);               
                result = new byte[numberOfRead];               
                Array.Copy(buff, result, numberOfRead);           
            }            return result;       
        }
    }
    enum Verbs   
    {       
        WILL = 251,       
        WONT = 252,       
        DO = 253,       
        DONT = 254,       
        IAC = 255   
    }   
    enum Options   
    {       
        RD = 1,       
        SGA = 3   
    }
}

posted @ 2012-06-05 16:28  尹成亮  阅读(10368)  评论(1编辑  收藏  举报