三個Telnet連接類----來自網絡

聲明:下面的三個類都是從網上找到的,具體出處不詳,哪一個類的好壞性能優劣本身把握,可參考使用。拒絕使用商業用途,如產生版權糾紛和本人無關。linux

一:Telnet連接網絡設備,在網上看到C#Telnet鏈接網絡設備的類,程序爲命令行程序,具體代碼以下:windows

文件名:Program.cs服務器

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

namespace ConsoleTelnet
{
    public class TelNet
    {
        #region 一些telnet 的數據定義,先沒看懂不要緊
        /// <summary>   
        /// 標誌符,表明是一個TELNET 指令   
        /// </summary>   
        readonly Char IAC = Convert.ToChar(255);
        /// <summary>   
        /// 表示一方要求另外一方使用,或者確認你但願另外一方使用指定的選項。   
        /// </summary>   
        readonly Char DO = Convert.ToChar(253);
        /// <summary>   
        /// 表示一方要求另外一方中止使用,或者確認你再也不但願另外一方使用指定的選項。   
        /// </summary>   
        readonly Char DONT = Convert.ToChar(254);
        /// <summary>   
        /// 表示但願開始使用或者確認所使用的是指定的選項。   
        /// </summary>   
        readonly Char WILL = Convert.ToChar(251);
        /// <summary>   
        /// 表示拒絕使用或者繼續使用指定的選項。   
        /// </summary>   
        readonly Char WONT = Convert.ToChar(252);
        /// <summary>   
        /// 表示後面所跟的是對須要的選項的子談判   
        /// </summary>   
        readonly Char SB = Convert.ToChar(250);
        /// <summary>   
        /// 子談判參數的結束   
        /// </summary>   
        readonly Char SE = Convert.ToChar(240);
        const Char IS = '0';
        const Char SEND = '1';
        const Char INFO = '2';
        const Char VAR = '0';
        const Char VALUE = '1';
        const Char ESC = '2';
        const Char USERVAR = '3';
        /// <summary>   
        ////// </summary>   
        byte[] m_byBuff = new byte[100000];
        /// <summary>   
        /// 收到的控制信息   
        /// </summary>   
        private ArrayList m_ListOptions = new ArrayList();
        /// <summary>   
        /// 存儲準備發送的信息   
        /// </summary>   
        string m_strResp;
        /// <summary>   
        /// 一個Socket 套接字   
        /// </summary>   
        private Socket s;
        #endregion
        /// <summary>   
        /// 主函數   
        /// </summary>   
        /// <param name="args"></param>   
        static void Main(string[] args)
        {
            //實例化這個對象   
            TelNet p = new TelNet();
            //啓動socket 進行telnet 連接   
            p.doSocket();
        }
        /// <summary>   
        /// 啓動socket 進行telnet 操做   
        /// </summary>   
        private void doSocket()
        {
            //得到連接的地址,能夠是網址也能夠是IP   
            Console.WriteLine("Server Address:");
            //解析輸入,若是是一個網址,則解析成ip   
            IPAddress import = GetIP(Console.ReadLine());

            //得到端口號   
            Console.WriteLine("Server Port:");
            int port = int.Parse(Console.ReadLine());
            //創建一個socket 對象,使用IPV4,使用流進行鏈接,使用tcp/ip協議   
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //得到一個連接地址對象(由IP 地址和端口號構成)   
            IPEndPoint address = new IPEndPoint(import, port);
            /* 
            * 說明此socket 不是處於阻止模式 
            * 
            * msdn 對阻止模式的解釋: 
            * ============================================================ 
            * 若是當前處於阻止模式,而且進行了一個並不當即完成的方法調用, 
            * 則應用程序將阻止執行,直到請求的操做完成後才解除阻止。 
            * 若是但願在請求的操做還沒有完成的狀況下也能夠繼續執行, 
            * 請將Blocking 屬性更改成false。Blocking 屬性對異步方法無效。 
            * 若是當前正在異步發送和接收數據,並但願阻止執行, 
            * 請使用ManualResetEvent 類。 
            * ============================================================ 
            */
            s.Blocking = false;
            /* 
            * 開始一個對遠程主機鏈接的異步請求, 
            * 由於Telnet 使用的是TCP 連接,是面向鏈接的, 
            * 因此此處BeginConnect 會啓動一個異步請求, 
            (本文下載自防鏽油文檔綜合站www.hthrt.com。轉載請說明出處) 
            * 請求得到與給的address 的鏈接 
            * 
            * 此方法的第二個函數是一個類型爲AsyncCallback 的委託 
            * 
            * 這個AsyncCallback msdn 給出的定義以下 
            * =================================================================== 
            * 使用AsyncCallback 委託在一個單獨的線程中處理異步操做的結果。A 
            * syncCallback 委託表示在異步操做完成時調用的回調方法。 
            * 回調方法採用IAsyncResult 參數,該參數隨後可用來獲取異步操做的結果。 
            * =================================================================== 
            * 這個方法裏的委託實際上就是當異步請求有迴應了以後,執行委託的方法. 
            * 委託裏的參數,實際上就是BeginConnect 的第三個參數, 
            * 此處爲socket 自己 
            *(本文下載自防鏽油文檔綜合站www.hthrt.com。轉載請說明出處) 
            * 我比較懶,寫了一個匿名委託,實際上跟AsyncCallback 效果一個樣. 
            * 
            */
            s.BeginConnect(
            address,
            delegate(IAsyncResult ar)
            /* 
            * 此處爲一個匿名委託, 
            * 實際上等於 
            * 創建一個AsyncCallback 對象,指定後在此引用一個道理 
            * 
            * ok 這裏的意義是, 
            * 當遠程主機鏈接的異步請求有響應的時候,執行如下語句 
            */
            {
                try
                {
                    //得到傳入的對象(此處對象是BeginConnect 的第三個參數)   
                    Socket sock1 = (Socket)ar.AsyncState;

                    /* 
                    * 若是Socket 在最近操做時鏈接到遠程資源,則爲true;不然爲false。 
                    * 
                    * 如下是MSDN 對Connected 屬性的備註信息 
                    * 
                    ========================================================================= 
                    * Connected 屬性獲取截止到最後的I/O 操做時Socket 的鏈接狀態。 
                    * 當它返回false 時,代表Socket 要麼從未鏈接,要麼已斷開鏈接。 
                    * 
                    * Connected 屬性的值反映最近操做時的鏈接狀態。若是您須要肯定鏈接的當前狀態, 
                    * 請進行非阻止、零字節的Send 調用。 
                    (本文下載自防鏽油文檔綜合站www.hthrt.com。轉載請說明出處) 
                    * 若是該調用成功返回或引起WAEWOULDBLOCK 錯誤代碼(10035), 
                    * 則該套接字仍然處於鏈接狀態;不然,該套接字再也不處於鏈接狀態。 
                    * 
                    ========================================================================= 
                    */
                    if (sock1.Connected)
                    {
                        AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
                        /* 
                        * 此處沒再用匿名委託的緣由是, 
                        * 一個匿名委託嵌套一個匿名委託,我本身思路跟不上來了... 
                        * 
                        * ok,這裏是當Connected 爲true 時, 
                        * 使用BeginReceive 方法 
                        * 開始接收信息到m_byBuff(咱們在類中定義的私有屬性) 
                        * 
                        * 如下是MSDN 對BeginReceive 的一些說明 
                        * 
                        ========================================================================= 
                        * 異步BeginReceive 操做必須經過調用EndReceive 方法來完成。 
                        * 一般,該方法由callback 委託調用。此方法在操做完成前不會進入阻止狀態。* 若要 
                        一直阻塞到操做完成時爲止,請使用Receive 方法重載中的一個。 
                        * 若要取消掛起的BeginReceive,請調用Close 方法。* 
                        ========================================================================== 
                        * 
                        * 當接收完成以後,他們就會調用OnRecievedData 方法 
                        * 我在recieveData 所委託的方法OnRecievedData 中調用了sock.EndReceive(ar); 
                        */
                        sock1.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock1);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("初始化接收信息出錯:" + ex.Message);
                }
            },
            s);
            //此處是爲了發送指令而不停的循環   
            while (true)
            {
                //發送讀出的數據   
                DispatchMessage(Console.ReadLine());
                //由於每發送一行都沒有發送回車,故在此處補上   
                DispatchMessage("\r\n");
            }
        }
        /// <summary>   
        /// 當接收完成後,執行的方法(供委託使用)   
        /// </summary>   
        /// <param name="ar"></param>   
        private void OnRecievedData(IAsyncResult ar)
        {
            //從參數中得到給的socket 對象   
            Socket sock = (Socket)ar.AsyncState;
            /* 
            * EndReceive 方法爲結束掛起的異步讀取 
            * (貌似是在以前的beginReceive 收到數據以後, 
            * socket 只是"掛起",並未結束) 
            * 以後返回總共接收到的字流量 
            * 
            * 如下是MSDN 給出的EndReceive 的注意事項 
            * 
            ========================================================================================= 
            * EndReceive 方法完成在BeginReceive 方法中啓動的異步讀取操做。 
            * 
            * 在調用BeginReceive 以前,需建立一個實現AsyncCallback 委託的回調方法。 
            * 該回調方法在單獨的線程中執行並在BeginReceive 返回後由系統調用。 
            * 回調方法必須接受BeginReceive 方法所返回的IAsyncResult 做爲參數。 
            * 
            * 在回調方法中,調用IAsyncResult 的AsyncState 方法以獲取傳遞給BeginReceive 方法的狀態對象。 
            * 從該狀態對象提取接收Socket。在獲取Socket 以後,能夠調用EndReceive 方法以成功完成讀取操做, 
            * 並返回已讀取的字節數。 
            * 
            * EndReceive 方法將一直阻止到有數據可用爲止。 
            * 若是您使用的是無鏈接協議,則EndReceive 將讀取傳入網絡緩衝區中第一個排隊的可用數據報。 
            * 若是您使用的是面向鏈接的協議,則EndReceive 方法將讀取全部可用的數據, 
            * 直到達到BeginReceive 方法的size 參數所指定的字節數爲止。 
            * 若是遠程主機使用Shutdown 方法關閉了Socket 鏈接,而且全部可用數據均已收到, 
            * 則EndReceive 方法將當即完成並返回零字節。 
            * 
            * 若要獲取接收到的數據,請調用IAsyncResult 的AsyncState 方法, 
            * 而後提取所產生的狀態對象中包含的緩衝區。 
            * 
            * 若要取消掛起的BeginReceive,請調用Close 方法。 
            * 
            ========================================================================================= 
            */
            int nBytesRec = sock.EndReceive(ar);
            //若是有接收到數據的話   
            if (nBytesRec > 0)
            {
                //將接收到的數據轉個碼,順便轉成string 型   
                string sRecieved = Encoding.GetEncoding("utf-8").GetString(m_byBuff, 0, nBytesRec);

                //聲明一個字符串,用來存儲解析過的字符串   
                string m_strLine = "";
                //遍歷Socket 接收到的字符   
                /* 
                * 此循環用來調整linux 和windows 在換行上標記的區別 
                * 最後將調整好的字符賦予給m_strLine 
                */
                for (int i = 0; i < nBytesRec; i++)
                {
                    Char ch = Convert.ToChar(m_byBuff[i]);
                    switch (ch)
                    {
                        case '\r':
                            m_strLine += Convert.ToString("\r\n");
                            break;
                        case '\n':
                            break;
                        default:
                            m_strLine += Convert.ToString(ch);
                            break;
                    }
                }
                try
                {
                    //得到轉義後的字符串的長度   
                    int strLinelen = m_strLine.Length;
                    //若是長度爲零   
                    if (strLinelen == 0)
                    {
                        //則返回"\r\n" 即回車換行   
                        m_strLine = Convert.ToString("\r\n");
                    }
                    //創建一個流,把接收的信息(轉換後的)存進mToProcess 中   
                    Byte[] mToProcess = new Byte[strLinelen];
                    for (int i = 0; i < strLinelen; i++)
                        mToProcess[i] = Convert.ToByte(m_strLine[i]);
                    // Process the incoming data   
                    //對接收的信息進行處理,包括對傳輸過來的信息的參數的存取和   
                    string mOutText = ProcessOptions(mToProcess);
                    mOutText = ConvertToGB2312(mOutText);

                    //解析命令後返回顯示信息(即除掉了控制信息)   
                    if (mOutText != "")
                        Console.Write(mOutText);
                    // Respond to any incoming commands   
                    //接收完數據,處理完字符串數據等一系列事物以後,開始回發數據   
                    RespondToOptions();
                }
                catch (Exception ex)
                {
                    throw new Exception("接收數據的時候出錯了! " + ex.Message);
                }
            }
            else// 若是沒有接收到任何數據的話   
            {
                // 輸出關閉鏈接   
                Console.WriteLine("Disconnected", sock.RemoteEndPoint);
                // 關閉socket   
                sock.Shutdown(SocketShutdown.Both);
                sock.Close();
                Console.Write("Game Over");
                Console.ReadLine();
            }
        }
        /// <summary>   
        /// 發送數據的函數   
        /// </summary>   
        private void RespondToOptions()
        {
            try
            {
                //聲明一個字符串,來存儲接收到的參數   
                string strOption;
                /* 
                * 此處的控制信息參數,是以前接受到信息以後保存的 
                * 例如255 253 23 等等 
                * 具體參數的含義須要去查telnet 協議 
                */
                for (int i = 0; i < m_ListOptions.Count; i++)
                {
                    //得到一個控制信息參數   
                    strOption = (string)m_ListOptions[i];
                    //根據這個參數,進行處理   
                    ArrangeReply(strOption);
                }
                DispatchMessage(m_strResp);
                m_strResp = "";
                m_ListOptions.Clear();
            }
            catch (Exception ers)
            {
                Console.WriteLine("錯錯了,在回發數據的時候" + ers.Message);
            }
        }
        /// <summary>   
        /// 解析接收的數據,生成最終用戶看到的有效文字,同時將附帶的參數存儲起來   
        /// </summary>   
        /// <param name="m_strLineToProcess">收到的處理後的數據</param>   
        /// <returns></returns>   
        private string ProcessOptions(byte[] m_strLineToProcess)
        {
            string m_DISPLAYTEXT = "";
            string m_strTemp = "";
            string m_strOption = "";
            string m_strNormalText = "";
            bool bScanDone = false;
            int ndx = 0;
            int ldx = 0;
            char ch;
            try
            {
                //把數據從byte[] 轉化成string   
                for (int i = 0; i < m_strLineToProcess.Length; i++)
                {
                    Char ss = Convert.ToChar(m_strLineToProcess[i]);
                    m_strTemp = m_strTemp + Convert.ToString(ss);
                }
                //此處意義爲,當沒描完數據前,執行掃描   
                while (bScanDone != true)
                {
                    //得到長度   
                    int lensmk = m_strTemp.Length;
                    //以後開始分析指令,由於每條指令爲255 開頭,故能夠用此來區分出每條指令   
                    ndx = m_strTemp.IndexOf(Convert.ToString(IAC));
                    //此處爲出錯判斷,本無其餘含義   
                    if (ndx > lensmk)
                        ndx = m_strTemp.Length;
                    //此處爲,若是搜尋到IAC 標記的telnet 指令,則執行如下步驟   
                    if (ndx != -1)
                    {
                        #region 若是存在IAC 標誌位
                        // 將標誌位IAC 的字符賦值給最終顯示文字   
                        m_DISPLAYTEXT += m_strTemp.Substring(0, ndx);
                        // 此處得到命令碼   
                        ch = m_strTemp[ndx + 1];
                        //若是命令碼是253(DO) 254(DONT) 521(WILL) 252(WONT) 的狀況下   
                        if (ch == DO || ch == DONT || ch == WILL || ch == WONT)
                        {
                            //將以IAC 開頭3個字符組成的整個命令存儲起來   
                            m_strOption = m_strTemp.Substring(ndx, 3);
                            m_ListOptions.Add(m_strOption);
                            // 將標誌位IAC 的字符賦值給最終顯示文字   
                            m_DISPLAYTEXT += m_strTemp.Substring(0, ndx);
                            //將處理過的字符串刪去   
                            string txt = m_strTemp.Substring(ndx + 3);
                            m_strTemp = txt;
                        }
                        //若是IAC 後面又跟了個IAC (255)   
                        else if (ch == IAC)
                        {
                            //則顯示從輸入的字符串頭開始,到以前的IAC 結束   
                            m_DISPLAYTEXT = m_strTemp.Substring(0, ndx);
                            //以後將處理過的字符串排除出去   
                            m_strTemp = m_strTemp.Substring(ndx + 1);
                        }
                        //若是IAC 後面跟的是SB(250)   
                        else if (ch == SB)
                        {
                            m_DISPLAYTEXT = m_strTemp.Substring(0, ndx);
                            ldx = m_strTemp.IndexOf(Convert.ToString(SE));
                            m_strOption = m_strTemp.Substring(ndx, ldx);
                            m_ListOptions.Add(m_strOption);
                            m_strTemp = m_strTemp.Substring(ldx);
                        }
                        #endregion
                    }
                    //若字符串裏已經沒有IAC 標誌位了   
                    else
                    {
                        //顯示信息累加上m_strTemp 存儲的字段   
                        m_DISPLAYTEXT = m_DISPLAYTEXT + m_strTemp;
                        bScanDone = true;
                    }
                }
                //輸出人看到的信息   
                m_strNormalText = m_DISPLAYTEXT;
            }
            catch (Exception eP)
            {
                throw new Exception("解析傳入的字符串錯誤:" + eP.Message);
            }
            return m_strNormalText;
        }
        /// <summary>   
        /// 得到IP 地址   
        /// </summary>   
        /// <param name="import"></param>   
        /// <returns></returns>   
        private static IPAddress GetIP(string import)
        {
            //IPHostEntry IPHost = Dns.GetHostEntry(import);
            //IPHostEntry IPHost = Dns.GetHostByName(import);
            IPAddress[] IPHost = Dns.GetHostAddresses(import);

            //return IPHost.AddressList[0];
            return IPHost[0];

            //return IPHost;
        }
        #region magic Function
        //解析傳過來的參數,生成回發的數據到m_strResp   
        private void ArrangeReply(string strOption)
        {
            try
            {
                Char Verb;
                Char Option;
                Char Modifier;
                Char ch;
                bool bDefined = false;
                //排錯選項,無啥意義   
                if (strOption.Length < 3) return;
                //得到命令碼   
                Verb = strOption[1];
                //得到選項碼   
                Option = strOption[2];
                //若是選項碼爲回顯(1) 或者是抑制繼續進行(3)   
                if (Option == 1 || Option == 3)
                {
                    bDefined = true;
                }
                // 設置回發消息,首先爲標誌位255   
                m_strResp += IAC;
                //若是選項碼爲回顯(1) 或者是抑制繼續進行(3) ==true   
                if (bDefined == true)
                {
                    #region 繼續判斷
                    //若是命令碼爲253 (DO)   
                    if (Verb == DO)
                    {
                        //我設置我應答的命令碼爲251(WILL) 即爲支持回顯或抑制繼續進行   
                        ch = WILL;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    //若是命令碼爲254(DONT)   
                    if (Verb == DONT)
                    {
                        //我設置我應答的命令碼爲252(WONT) 即爲我也會"拒絕啓動" 回顯或抑制繼續進行   
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    //若是命令碼爲251(WILL)   
                    if (Verb == WILL)
                    {
                        //我設置我應答的命令碼爲253(DO) 即爲我承認你使用回顯或抑制繼續進行   
                        ch = DO;
                        m_strResp += ch;
                        m_strResp += Option;
                        //break;   
                    }
                    //若是接受到的命令碼爲251(WONT)   
                    if (Verb == WONT)
                    {
                        //應答我也拒絕選項請求回顯或抑制繼續進行   
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                        // break;   
                    }
                    //若是接受到250(sb,標誌子選項開始)   
                    if (Verb == SB)
                    {
                        /* 
                        * 由於啓動了子標誌位,命令長度擴展到了4字節, 
                        * 取最後一個標誌字節爲選項碼 
                        * 若是這個選項碼字節爲1(send) 
                        * 則回發爲250(SB 子選項開始) + 獲取的第二個字節+ 0(is) + 255(標誌位IAC) + 240(SE 子 
                        選項結束) 
                        */
                        Modifier = strOption[3];
                        if (Modifier == SEND)
                        {
                            ch = SB;
                            m_strResp += ch;
                            m_strResp += Option;
                            m_strResp += IS;
                            m_strResp += IAC;
                            m_strResp += SE;
                        }
                    }
                    #endregion
                }
                else //若是選項碼不是1 或者3   
                {
                    #region 底下一系列表明,不管你發那種請求,我都不幹
                    if (Verb == DO)
                    {
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == DONT)
                    {
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == WILL)
                    {
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == WONT)
                    {
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    #endregion
                }
            }
            catch (Exception eeeee)
            {
                throw new Exception("解析參數時出錯:" + eeeee.Message);
            }
        }
        /// <summary>   
        /// 將信息轉化成charp[] 流的形式,使用socket 進行發出   
        /// 發出結束以後,使用一個匿名委託,進行接收,   
        /// 以後這個委託裏,又有個委託,意思是接受完了以後執行OnRecieveData 方法   
        ///   
        /// </summary>   
        /// <param name="strText"></param>   
        void DispatchMessage(string strText)
        {
            try
            {
                //申請一個與字符串至關長度的char 流   
                Byte[] smk = new Byte[strText.Length];
                for (int i = 0; i < strText.Length; i++)
                {
                    //解析字符串,將其存儲到char 流中去   
                    Byte ss = Convert.ToByte(strText[i]);
                    smk[i] = ss;
                }
                //發送char 流,以後發送完畢後執行委託中的方法(此處爲匿名委託)   
                /*MSDN 對BeginSend 的解釋 
                * 
                ============================================================================================ 
                =========== 
                * BeginSend 方法可對在Connect、BeginConnect、Accept 或BeginAccept 方法中創建的遠程主機啓 
                動異步發送操做。 
                * 若是沒有首先調用Accept、BeginAccept、Connect 或BeginConnect,則BeginSend 將會引起異常。 
                * 調用BeginSend 方法將使您可以在單獨的執行線程中發送數據。 
                * 您能夠建立一個實現AsyncCallback 委託的回調方法並將它的名稱傳遞給BeginSend 方法。 
                * 爲此,您的state 參數至少必須包含用於通訊的已鏈接或默認Socket。 
                * 若是回調須要更多信息,則能夠建立一個小型類或結構,用於保存Socket 和其餘所需的信息。 
                * 經過state 參數將此類的一個實例傳遞給BeginSend 方法。 
                * 回調方法應調用EndSend 方法。 
                * 當應用程序調用BeginSend 時,系統將使用一個單獨的線程來執行指定的回調方法, 
                * 並阻止EndSend,直到Socket 發送了請求的字節數或引起了異常爲止。 
                * 若是但願在調用BeginSend 方法以後使原始線程阻止,請使用WaitHandle.WaitOne 方法。 
                * 當須要原始線程繼續執行時,請在回調方法中調用T:System.Threading.ManualResetEvent 的Set 方 
                法。 
                * 有關編寫回調方法的其餘信息,請參見Callback 示例。 
                * 
                ============================================================================================ 
                =========== 
                */
                IAsyncResult ar2 = s.BeginSend(smk, 0, smk.Length, SocketFlags.None, delegate(IAsyncResult ar)
                {
                    //當執行完"發送數據" 這個動做後   
                    // 獲取Socket 對象,對象從beginsend 中的最後個參數上得到   
                    Socket sock1 = (Socket)ar.AsyncState;
                    if (sock1.Connected)//若是鏈接仍是有效   
                    {
                        //這裏創建一個委託   
                        AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
                        /* 
                        * 此處爲:開始接受數據(在發送完畢以後-->出自於上面的匿名委託), 
                        * 當接收完信息以後,執行OnrecieveData 方法(由委託傳進去), 
                        * 注意,是異步調用 
                        */
                        sock1.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock1);
                    }
                }, s);
                /* 
                * 結束異步發送 
                * EndSend 完成在BeginSend 中啓動的異步發送操做。 
                * 在調用BeginSend 以前,需建立一個實現AsyncCallback 委託的回調方法。 
                * 該回調方法在單獨的線程中執行並在BeginSend 返回後由系統調用。 
                * 回調方法必須接受BeginSend 方法所返回的IAsyncResult 做爲參數。 
                * 
                * 在回調方法中,調用IAsyncResult 參數的AsyncState 方法能夠獲取發送Socket。 
                * 在獲取Socket 以後,則能夠調用EndSend 方法以成功完成發送操做,並返回發送的字節數。 
                */
                s.EndSend(ar2);
            }
            catch (Exception ers)
            {
                Console.WriteLine("出錯了,在回發數據的時候:" + ers.Message);
            }
        }
        #endregion

        /// <param name="str_origin">必要轉換的字符串</param>   
        /// <returns>轉換後的字符串</returns>   
        private string ConvertToGB2312(string str_origin)
        {
            char[] chars = str_origin.ToCharArray();
            byte[] bytes = new byte[chars.Length];
            for (int i = 0; i < chars.Length; i++)
            {
                int c = (int)chars[i];
                bytes[i] = (byte)c;
            }
            Encoding Encoding_GB2312 = Encoding.GetEncoding("GB2312");
            string str_converted = Encoding_GB2312.GetString(bytes);
            return str_converted;
        }

    }

}

 

二:Telnet類網絡

文件名:TelnetClass.cs異步

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

namespace EmptyProjectNet40_FineUI.App_Code.Helper
{

    //        //調用方法以下:
    //Telnet p = new Telnet("192.168.1.100", 23, 50);

    //if(p.Connect()==false)
    //{
    //  Console.WriteLine("鏈接失敗");
    //  return;
    //}
    ////等待指定字符返回後才執行下一命令
    //p.WaitFor("login:");
    //p.Send("admin");
    //p.WaitFor("password:");
    //p.Send("123456");
    //p.WaitFor(">");
    ////Console.WriteLine(p.SessionLog);
    //Console.WriteLine(p.WorkingData);
    //改進後代碼(注意標藍色的部分):




    public class Telnet
    {
        #region telnet的數據定義
        /// <summary>        
        /// 標誌符,表明是一個TELNET 指令        
        /// </summary>        
        readonly Char IAC = Convert.ToChar(255);
        /// <summary>        
        /// 表示一方要求另外一方使用,或者確認你但願另外一方使用指定的選項。
        /// </summary>        
        readonly Char DO = Convert.ToChar(253);
        /// <summary>
        /// 表示一方要求另外一方中止使用,或者確認你再也不但願另外一方使用指定的選項。       
        /// </summary>       
        readonly Char DONT = Convert.ToChar(254);
        /// <summary>
        /// 表示但願開始使用或者確認所使用的是指定的選項。
        /// </summary>
        readonly Char WILL = Convert.ToChar(251);
        /// <summary>
        /// 表示拒絕使用或者繼續使用指定的選項。
        /// </summary>
        readonly Char WONT = Convert.ToChar(252);
        /// <summary>
        /// 表示後面所跟的是對須要的選項的子談判
        /// </summary>
        readonly Char SB = Convert.ToChar(250);
        /// <summary>
        /// 子談判參數的結束
        /// </summary>
        readonly Char SE = Convert.ToChar(240);
        const Char IS = '0';
        const Char SEND = '1';
        const Char INFO = '2';
        const Char VAR = '0';
        const Char VALUE = '1';
        const Char ESC = '2';
        const Char USERVAR = '3';
        /// <summary> 
        ////// /// </summary>
        byte[] m_byBuff = new byte[100000];
        /// <summary>
        /// 收到的控制信息
        /// </summary>
        private ArrayList m_ListOptions = new ArrayList();
        /// <summary>
        /// 存儲準備發送的信息
        /// </summary>
        string m_strResp;
        /// <summary>
        /// 一個Socket套接字
        /// </summary>
        private Socket s;
        #endregion

        private IPEndPoint iep;
        private string address;
        private int port;
        private int timeout;

        private string strWorkingData = "";     // 保存從服務器端接收到的數據
        private string strFullLog = "";
        //==== 夏春濤 擴充 20110531 ================================================            

        private string strWorkingDataX = "";
        //用於獲取當前工做的數據內容

        public string WorkingData
        {
            get { return strWorkingDataX; }
        }
        //===================================================================
        public Telnet(string Address, int Port, int CommandTimeout)
        {
            address = Address;
            port = Port;
            timeout = CommandTimeout;
        }

        /// <summary>        
        /// 啓動socket 進行telnet操做        
        /// </summary>       
        public bool Connect()
        {
            
            IPAddress import = GetIP(address);
            //IPAddress import = address;

            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            iep = new IPEndPoint(import, port);

            try
            {
                // Try a blocking connection to the server
                s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                s.Connect(iep);

                //異步回調
                AsyncCallback recieveData = new AsyncCallback(OnRecievedData);
                s.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, s);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>        
        /// 當接收完成後,執行的方法(供委託使用)       
        /// </summary>      
        /// <param name="ar"></param>       
        private void OnRecievedData(IAsyncResult ar)
        {
            try
            {
                //從參數中得到給的socket 對象           
                Socket sock = (Socket)ar.AsyncState;

                //EndReceive方法爲結束掛起的異步讀取         
                int nBytesRec = sock.EndReceive(ar);
                //若是有接收到數據的話            
                if (nBytesRec > 0)
                {
                    //聲明一個字符串,用來存儲解析過的字符串                
                    string m_strLine = "";
                    //遍歷Socket接收到的字符                 
                    /*       
                     * 此循環用來調整linux 和 windows在換行上標記的區別       
                     * 最後將調整好的字符賦予給 m_strLine      
                     */
                    for (int i = 0; i < nBytesRec; i++)
                    {
                        Char ch = Convert.ToChar(m_byBuff[i]);
                        switch (ch)
                        {
                            case '\r':
                                m_strLine += Convert.ToString("\r\n");
                                break;
                            case '\n':
                                break;
                            default:
                                m_strLine += Convert.ToString(ch);
                                break;
                        }
                    }
                    try
                    {
                        //得到轉義後的字符串的長度                  
                        int strLinelen = m_strLine.Length;
                        //若是長度爲零                   
                        if (strLinelen == 0)
                        {
                            //則返回"\r\n" 即回車換行                    
                            m_strLine = Convert.ToString("\r\n");
                        }
                        //創建一個流,把接收的信息(轉換後的)存進 mToProcess 中   
                        Byte[] mToProcess = new Byte[strLinelen];
                        for (int i = 0; i < strLinelen; i++)
                            mToProcess[i] = Convert.ToByte(m_strLine[i]);
                        //對接收的信息進行處理,包括對傳輸過來的信息的參數的存取和       
                        string mOutText = ProcessOptions(mToProcess);
                        //==== 夏春濤 擴充 20110531 ==============================================
                        mOutText = ConvertToGB2312(mOutText);
                        strWorkingDataX = mOutText;
                        //===================================================================
                        //解析命令後返回 顯示信息(即除掉了控制信息)                        
                        if (mOutText != "")
                        {
                            //Console.Write(mOutText);//顯示輸出//夏春濤 去掉 20110531/////////////////////////
                            strWorkingData = mOutText;
                            strFullLog += mOutText;
                        }
                        //接收完數據,處理完字符串數據等一系列事物以後,開始回發數據          
                        RespondToOptions();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("接收數據的時候出錯了! " + ex.Message);
                    }
                }
                else// 若是沒有接收到任何數據的話           
                {
                    // 關閉鏈接            
                    // 關閉socket               
                    sock.Shutdown(SocketShutdown.Both);
                    sock.Close();
                }
            }
            catch { }
        }
        /// <summary>        
        ///  發送數據的函數       
        /// </summary>        
        private void RespondToOptions()
        {
            try
            {
                //聲明一個字符串,來存儲 接收到的參數            
                string strOption;
                /*               
                 * 此處的控制信息參數,是以前接受到信息以後保存的              
                 * 例如 255   253   23   等等                                
                 */
                for (int i = 0; i < m_ListOptions.Count; i++)
                {
                    //得到一個控制信息參數                   
                    strOption = (string)m_ListOptions[i];
                    //根據這個參數,進行處理                   
                    ArrangeReply(strOption);
                }
                DispatchMessage(m_strResp);
                m_strResp = "";
                m_ListOptions.Clear();
            }
            catch (Exception ers)
            {
                Console.WriteLine("出錯了,在回發數據的時候 " + ers.Message);

            }
        }
        /// <summary>        
        /// 解析接收的數據,生成最終用戶看到的有效文字,同時將附帶的參數存儲起來       
        ///</summary>       
        ///<param name="m_strLineToProcess">收到的處理後的數據</param>     
        /// <returns></returns>     
        private string ProcessOptions(byte[] m_strLineToProcess)
        {
            string m_DISPLAYTEXT = "";
            string m_strTemp = "";
            string m_strOption = "";
            string m_strNormalText = "";
            bool bScanDone = false;
            int ndx = 0;
            int ldx = 0;
            char ch;
            try
            {
                //把數據從byte[] 轉化成string    
                for (int i = 0; i < m_strLineToProcess.Length; i++)
                {
                    Char ss = Convert.ToChar(m_strLineToProcess[i]);
                    m_strTemp = m_strTemp + Convert.ToString(ss);
                }

                //此處意義爲,當沒描完數據前,執行掃描      
                while (bScanDone != true)
                {
                    //得到長度                
                    int lensmk = m_strTemp.Length;
                    //以後開始分析指令,由於每條指令爲255 開頭,故能夠用此來區分出每條指令 
                    ndx = m_strTemp.IndexOf(Convert.ToString(IAC));
                    //此處爲出錯判斷,本無其餘含義               
                    if (ndx > lensmk)
                        ndx = m_strTemp.Length;

                    //此處爲,若是搜尋到IAC標記的telnet 指令,則執行如下步驟        
                    if (ndx != -1)
                    {
                        #region 若是存在IAC標誌位
                        // 將 標誌位IAC 的字符 賦值給最終顯示文字           
                        m_DISPLAYTEXT += m_strTemp.Substring(0, ndx);
                        // 此處得到命令碼              
                        ch = m_strTemp[ndx + 1];
                        //若是命令碼是253(DO) 254(DONT)  521(WILL) 252(WONT) 的狀況下 
                        if (ch == DO || ch == DONT || ch == WILL || ch == WONT)
                        {

                            //將以IAC 開頭3個字符組成的整個命令存儲起來          
                            m_strOption = m_strTemp.Substring(ndx, 3);
                            m_ListOptions.Add(m_strOption);
                            // 將 標誌位IAC 的字符 賦值給最終顯示文字                         
                            m_DISPLAYTEXT += m_strTemp.Substring(0, ndx);
                            //將處理過的字符串刪去                          
                            string txt = m_strTemp.Substring(ndx + 3);
                            m_strTemp = txt;
                        }
                        //若是IAC後面又跟了個IAC (255)  
                        else if (ch == IAC)
                        {
                            //則顯示從輸入的字符串頭開始,到以前的IAC 結束        
                            m_DISPLAYTEXT = m_strTemp.Substring(0, ndx);
                            //以後將處理過的字符串排除出去                  
                            m_strTemp = m_strTemp.Substring(ndx + 1);
                        }
                        //若是IAC後面跟的是SB(250)       
                        else if (ch == SB)
                        {
                            m_DISPLAYTEXT = m_strTemp.Substring(0, ndx);
                            ldx = m_strTemp.IndexOf(Convert.ToString(SE));
                            m_strOption = m_strTemp.Substring(ndx, ldx);
                            m_ListOptions.Add(m_strOption);
                            m_strTemp = m_strTemp.Substring(ldx);
                        }
                        #endregion
                    }
                    //若字符串裏已經沒有IAC標誌位了  
                    else
                    {

                        //顯示信息累加上m_strTemp存儲的字段      
                        m_DISPLAYTEXT = m_DISPLAYTEXT + m_strTemp;
                        bScanDone = true;
                    }
                }
                //輸出人看到的信息    
                m_strNormalText = m_DISPLAYTEXT;
            }
            catch (Exception eP)
            {
                throw new Exception("解析傳入的字符串錯誤:" + eP.Message);
            }

            return m_strNormalText;
        }
        /// <summary>      
        /// 得到IP地址      
        /// </summary>       
        /// <param name="import"></param>    
        /// <returns></returns>   
        private static IPAddress GetIP(string import)
        {
            IPHostEntry IPHost = Dns.GetHostEntry(import);
            return IPHost.AddressList[0];
        }

        #region magic Function
        //解析傳過來的參數,生成回發的數據到m_strResp   
        private void ArrangeReply(string strOption)
        {
            try
            {
                Char Verb;
                Char Option;
                Char Modifier;
                Char ch;
                bool bDefined = false;
                //排錯選項,無啥意義              
                if (strOption.Length < 3) return;
                //得到命令碼               
                Verb = strOption[1];
                //得到選項碼             
                Option = strOption[2];
                //若是選項碼爲 回顯(1) 或者是抑制繼續進行(3)
                if (Option == 1 || Option == 3)
                {
                    bDefined = true;
                }
                // 設置回發消息,首先爲標誌位255         
                m_strResp += IAC;
                //若是選項碼爲 回顯(1) 或者是抑制繼續進行(3) ==true   
                if (bDefined == true)
                {
                    #region 繼續判斷
                    //若是命令碼爲253 (DO)             
                    if (Verb == DO)
                    {
                        //我設置我應答的命令碼爲 251(WILL) 即爲支持 回顯或抑制繼續進行     
                        ch = WILL;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    //若是命令碼爲 254(DONT)     
                    if (Verb == DONT)
                    {
                        //我設置我應答的命令碼爲 252(WONT) 即爲我也會"拒絕啓動" 回顯或抑制繼續進行
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    //若是命令碼爲251(WILL)   
                    if (Verb == WILL)
                    {
                        //我設置我應答的命令碼爲 253(DO) 即爲我承認你使用回顯或抑制繼續進行 
                        ch = DO;
                        m_strResp += ch;
                        m_strResp += Option;
                        //break;               
                    }
                    //若是接受到的命令碼爲251(WONT)         
                    if (Verb == WONT)
                    {
                        //應答  我也拒絕選項請求回顯或抑制繼續進行       
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                        //break;            
                    }
                    //若是接受到250(sb,標誌子選項開始)            
                    if (Verb == SB)
                    {
                        /*                  
                         * 由於啓動了子標誌位,命令長度擴展到了4字節,                    
                         * 取最後一個標誌字節爲選項碼                     
                         * 若是這個選項碼字節爲1(send)                    
                         * 則回發爲 250(SB子選項開始) + 獲取的第二個字節 + 0(is) + 255(標誌位IAC) + 240(SE子選項結束)               
                         */
                        Modifier = strOption[3];
                        if (Modifier == SEND)
                        {
                            ch = SB;
                            m_strResp += ch;
                            m_strResp += Option;
                            m_strResp += IS;
                            m_strResp += IAC;
                            m_strResp += SE;
                        }
                    }
                    #endregion
                }
                else //若是選項碼不是1 或者3 
                {
                    #region 底下一系列表明,不管你發那種請求,我都不幹
                    if (Verb == DO)
                    {
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == DONT)
                    {
                        ch = WONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == WILL)
                    {
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    if (Verb == WONT)
                    {
                        ch = DONT;
                        m_strResp += ch;
                        m_strResp += Option;
                    }
                    #endregion
                }
            }
            catch (Exception eeeee)
            {
                throw new Exception("解析參數時出錯:" + eeeee.Message);
            }
        }
        /// <summary>     
        /// 將信息轉化成charp[] 流的形式,使用socket 進行發出   
        /// 發出結束以後,使用一個匿名委託,進行接收,  
        /// 以後這個委託裏,又有個委託,意思是接受完了以後執行OnRecieveData 方法 
        ///       
        /// </summary>       
        /// <param name="strText"></param>  
        void DispatchMessage(string strText)
        {
            try
            {
                //申請一個與字符串至關長度的char流      
                Byte[] smk = new Byte[strText.Length];
                for (int i = 0; i < strText.Length; i++)
                {
                    //解析字符串,將其存儲到char流中去   
                    Byte ss = Convert.ToByte(strText[i]);
                    smk[i] = ss;
                }
                //發送char流,以後發送完畢後執行委託中的方法(此處爲匿名委託)    
                IAsyncResult ar2 = s.BeginSend(smk, 0, smk.Length, SocketFlags.None, delegate(IAsyncResult ar)
                {
                    //當執行完"發送數據" 這個動做後                  
                    // 獲取Socket對象,對象從beginsend 中的最後個參數上得到          
                    Socket sock1 = (Socket)ar.AsyncState;
                    if (sock1.Connected)//若是鏈接仍是有效                    
                    {
                        //這裏創建一個委託      
                        AsyncCallback recieveData = new AsyncCallback(OnRecievedData);

                        sock1.BeginReceive(m_byBuff, 0, m_byBuff.Length, SocketFlags.None, recieveData, sock1);

                    }
                }, s);

                s.EndSend(ar2);
            }
            catch (Exception ers)
            {
                Console.WriteLine("出錯了,在回發數據的時候:" + ers.Message);
            }
        }

        /// <summary>
        /// 等待指定的字符串返回
        /// </summary>
        /// <param name="DataToWaitFor">等待的字符串</param>
        /// <returns>返回0</returns>
        public int WaitFor(string DataToWaitFor)
        {
            long lngStart = DateTime.Now.AddSeconds(this.timeout).Ticks;
            long lngCurTime = 0;

            while (strWorkingData.ToLower().IndexOf(DataToWaitFor.ToLower()) == -1)
            {
                lngCurTime = DateTime.Now.Ticks;
                if (lngCurTime > lngStart)
                {
                    throw new Exception("Timed Out waiting for : " + DataToWaitFor);
                }
                Thread.Sleep(1);
            }
            strWorkingData = "";
            return 0;
        }

        public void Send(string message)
        {
            DispatchMessage(message);
            //由於每發送一行都沒有發送回車,故在此處補上         
            DispatchMessage("\r\n");
        }
        #endregion

        /// <summary>
        /// 取完整日誌
        /// </summary>
        public string SessionLog
        {
            get
            {
                return strFullLog;
            }
        }

        //======================================================================================
        /// <summary>
        /// 字符串編碼轉換,解決漢字顯示亂碼問題。

        /// 原始字符串中的漢字存儲的是漢字內碼,此代碼實質是將漢字內碼轉換爲GB2312編碼。(夏春濤20110531)
        /// </summary>
        /// <param name="str_origin">須要轉換的字符串</param>
        /// <returns>轉換後的字符串</returns>
        private string ConvertToGB2312(string str_origin)
        {
            char[] chars = str_origin.ToCharArray();
            byte[] bytes = new byte[chars.Length];
            for (int i = 0; i < chars.Length; i++)
            {
                int c = (int)chars[i];
                bytes[i] = (byte)c;
            }
            Encoding Encoding_GB2312 = Encoding.GetEncoding("GB2312");
            string str_converted = Encoding_GB2312.GetString(bytes);
            return str_converted;
        }
        //======================================================================================
    }
}

 

三:Ctelnet.cs類socket

using System;
using System.Text;
using System.Net.Sockets;
using FineUI;

/// <summary>
/// Summary description for ClassTelnet
/// </summary>
public class ClassTelnet
{
    TcpClient telnet_tcp_client;

    public string strhost;      // IP 地址
    public string strusername;  // username
    public string strpassword;  // password
    private int ilogin_wait_time = 200; //網絡延遲等待時間
    private int irecv_wait_time = 100; //網絡延遲等待時間

    //Telnet protocal key
    enum Verbs
    {
        WILL = 251,
        WONT = 252,
        DO = 253,
        DONT = 254,
        IAC = 255
    }
    public ClassTelnet()
    {
    }
    /**
     * Telnet 關閉鏈接
     */
    public void close_telnet()
    {
        try
        {
            if (telnet_tcp_client == null)
            {
                return;
            }
            if (telnet_tcp_client.Connected)
            {
                telnet_tcp_client.Close();
            }
        }
        catch (Exception ex)
        {
            //Consule.Write("異常");
            Alert.Show("異常");
        }
    }

    /**
     * Telnet鏈接到服務器
     */
    public bool open_connect()
    {
        bool blresult;
        string strtemp;

        blresult = true;

        try
        {
            // new socket
            telnet_tcp_client = new TcpClient(this.strhost, 23);

            System.Threading.Thread.Sleep(ilogin_wait_time);
            // read host info data
            strtemp = recv_data_from_host();
            //strtemp = ConvertToGB2312(strtemp);
            blresult = strtemp.TrimEnd().EndsWith(":");
            if (blresult == false)
            {
                Alert.Show("read host info data error");
                return blresult;
            }

            // username send to host
            blresult = send_data_to_host(this.strusername + "/n/r");
            if (blresult == false)
            {
                Alert.Show("username send error");
                return blresult;
            }

            System.Threading.Thread.Sleep(ilogin_wait_time);
            strtemp = recv_data_from_host();
            blresult = strtemp.TrimEnd().EndsWith(":");
            if (blresult == false)
            {
                return blresult;
            }

            // password send to host
            blresult = send_data_to_host(this.strpassword + "/n/r");
            if (blresult == false)
            {
                return blresult;
            }
            System.Threading.Thread.Sleep(ilogin_wait_time);
            strtemp = recv_data_from_host();
            if ((strtemp.Trim().LastIndexOf("#") > -1) ||
                (strtemp.Trim().LastIndexOf("$") > -1) ||
                (strtemp.Trim().LastIndexOf(">") > -1))
            {
                blresult = true;
            }
            else
            {
                blresult = false;
            }
        }
        catch (Exception ex)
        {
            blresult = false;
        }
        return blresult;
    }

    /**
     * 執行命令
     */
    public bool exec_command(string strcmd)
    {
        bool blresult;
        string strprompt;

        blresult = false;
        strprompt = "";

        if (telnet_tcp_client.Connected)
        {
            blresult = send_data_to_host(strcmd + "/n/r");
            if (blresult == false)
            {
                return false;
            }
            strprompt = "";

            strprompt = recv_data_from_host();

            if ((strprompt.Trim().LastIndexOf("#") > -1) ||
                (strprompt.Trim().LastIndexOf("$") > -1) ||
                (strprompt.Trim().LastIndexOf(">") > -1))
            {
                blresult = true;
                return blresult;
            }
        }
        return blresult;
    }

    /**
     * telnet向主機發送數據
     */
    public bool send_data_to_host(string strcmd)
    {
        try
        {
            // socket error時、return
            if (!telnet_tcp_client.Connected)
            {
                return false;
            }

            byte[] bbuf = System.Text.ASCIIEncoding.ASCII.GetBytes(strcmd.Replace("/0xFF", "/0xFF/0xFF"));

            telnet_tcp_client.GetStream().Write(bbuf, 0, bbuf.Length);
        }
        catch (Exception ex)
        {
            return false;
        }
        return true;
    }

    /**
     * Telnet從主機接受數據
     */
    public string recv_data_from_host()
    {
        int iinput_data;    //data
        int inputverb;
        int inputoption;
        StringBuilder sbtemp;
        NetworkStream ns_temp;
        byte[] bread_buffer;
        StringBuilder sbcomplete_message;
        int iread_bytes_num;

        sbtemp = new StringBuilder();

        // socket沒有鏈接的時候,返回空
        if (!telnet_tcp_client.Connected)
        {
            return null;
        }

        do
        {
            // read 1 byte
            iinput_data = telnet_tcp_client.GetStream().ReadByte();
            switch (iinput_data)
            {
                case -1:
                    break;
                case (int)Verbs.IAC: // 接受的數據有keyword

                    // read 1 byte
                    inputverb = telnet_tcp_client.GetStream().ReadByte();
                    if (inputverb == -1) break;
                    switch (inputverb)
                    {
                        case (int)Verbs.IAC:
                            sbtemp.Append(inputverb);
                            break;
                        case (int)Verbs.DO:
                        case (int)Verbs.DONT:
                        case (int)Verbs.WILL:
                        case (int)Verbs.WONT:
                            inputoption = telnet_tcp_client.GetStream().ReadByte();
                            if (inputoption == -1) break;
                            telnet_tcp_client.GetStream().WriteByte((byte)Verbs.IAC);
                            telnet_tcp_client.GetStream().WriteByte(inputverb ==
                            (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
                            telnet_tcp_client.GetStream().WriteByte((byte)inputoption);
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    sbtemp.Append((char)iinput_data);
                    bread_buffer = new byte[8192];
                    sbcomplete_message = new StringBuilder();
                    iread_bytes_num = 0;
                    ns_temp = telnet_tcp_client.GetStream();
                    if (ns_temp.CanRead)
                    {
                        System.Threading.Thread.Sleep(ilogin_wait_time);
                        iread_bytes_num = ns_temp.Read(bread_buffer, 0, bread_buffer.Length);
                        sbtemp.AppendFormat("{0}", Encoding.ASCII.GetString(bread_buffer,
                                            0, iread_bytes_num));
                    }
                    break;
            }

            // timeout
            System.Threading.Thread.Sleep(irecv_wait_time);
        } while (telnet_tcp_client.Available > 0);

        // 返回接受的數據
        return sbtemp.ToString();
    }

    /**
     * 例子程序
     */
    public bool exec_sample()
    {
        bool blsts;
        blsts = true;

        // 關閉Telnet鏈接
        this.close_telnet();

        // telnet鏈接到遠程主機
        blsts = this.open_connect();
        if (blsts == false)
        {
            return blsts;
        }

        // 在遠程主機上執行命令
        blsts = this.exec_command("echo ABC");
        // 執行失敗
        if (blsts == false)
        {
            Alert.Show("命令執行失敗");
        }
        return blsts;
    }
    //======================================================================================
    /// <summary>
    /// 字符串編碼轉換,解決漢字顯示亂碼問題。

    /// 原始字符串中的漢字存儲的是漢字內碼,此代碼實質是將漢字內碼轉換爲GB2312編碼。(夏春濤20110531)
    /// </summary>
    /// <param name="str_origin">須要轉換的字符串</param>
    /// <returns>轉換後的字符串</returns>
    private string ConvertToGB2312(string str_origin)
    {
        char[] chars = str_origin.ToCharArray();
        byte[] bytes = new byte[chars.Length];
        for (int i = 0; i < chars.Length; i++)
        {
            int c = (int)chars[i];
            bytes[i] = (byte)c;
        }
        Encoding Encoding_GB2312 = Encoding.GetEncoding("GB2312");
        string str_converted = Encoding_GB2312.GetString(bytes);
        return str_converted;
    }
    //======================================================================================
   
}
相關文章
相關標籤/搜索