外国老的.net telnet 讲解


I feel your pain. I have been trying to figure this out on and off for quite a while. I am trying to do basically the same thing in c# and was having similar difficulties. I am connecting to a SUN OS server and only need to send one command. I finally had some success today that I thought I would share my results since my searches turned up many questions about it but no easy solutions. I finally figured out that you don't have to answer all of the server's requests for negotiations (or at least I didn't). The first thing I did after connecting up and getting the stream was to let the server know I wasn't interested in negotiating all the options that it seemed to want to do. The sun box was asking for the following:
Do terminal type
Do negotiate about window size
Do x display location
Do new environment option
Do environment option

I sent the following commands
WONT terminal type
WONT window size
WONT x display location
WONT new environment option
WONT environment option

I then sent
DO echo
DO suppress go ahead

I was then able to watch for the server to finally give me the login: prompt I have been trying to get.

Next I send the password followed by \r\n
I then wait for the desired password again followed by \r\n
For some reason (maybe the server wasn't quite ready for it or something) the server only received the \r\n
I haven't figured out an easy fix for that yet but if I just resend the password \r\n am able to log in.
I then wait for last login: and when I get that I can finally send my command.

Here's the code I used. I am not an experienced programmer and people may find many flaws to this logic but this thing has irritated me so much that once I finally had some degree of success I wanted to share the wealth so hopefully I could save someone else a few hours. I wrote this in C# 2008 express but it should be very similar to what you are trying to do.

Here are two methods or subs I created to cut down on the repetition.
Code:
        public string WriteNReadBuffer(byte [] TelnetNegotiation, NetworkStream stream)
    {
            stream.Write(TelnetNegotiation, 0, TelnetNegotiation.Length);
            Byte[] data = new Byte[256];
            Int32 bytes = stream.Read(data, 0, data.Length);
            string returnval;
            returnval = BitConverter.ToString(data, 0, bytes) + "\r\n";
            //textBox2.AppendText(BitConverter.ToString(data, 0, bytes) + "\r\n");
            return returnval;
    }
        public void Wait4Prompt(string PromptSearch, NetworkStream stream)
        {
            Byte[] data6 = new Byte[256];
            Int32 bytes6 = stream.Read(data6, 0, data6.Length);
            string bufferstring = (BitConverter.ToString(data6, 0, bytes6) + "\r\n");

            //Wait for particular prompt - Look for hex value for login: or password:
            while ((bufferstring.Contains(PromptSearch) != true))
            {
                Byte[] data7 = new Byte[256];
                Int32 bytes7 = stream.Read(data7, 0, data7.Length);
                bufferstring = (BitConverter.ToString(data7, 0, bytes7) + "\r\n");
            }
        }
I had a simple form set up for my testing. You basically just need to create a form with a button and multiline text box. Adjust the code as needed. Here's the code that runs on the click of the button.
Code:
        private void button3_Click(object sender, EventArgs e)
        {
            string server = "10.x.x.x";
            Int32 port = 23;
            TcpClient client = new TcpClient(server, port);
            NetworkStream stream = client.GetStream();

//          WONT terminal type, window size, x display location, new environment option, environment option
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 255, 252, 24, 255, 252, 31, 255, 252, 35, 255, 252, 39, 255, 252, 36 }, stream));

//          DO echo, suppress go ahead
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 255, 253, 01, 255, 253, 03 }, stream));

            //Wait for login prompt - Look for hex value for login:
            Wait4Prompt("6C-6F-67-69-6E-3A-20\r\n",stream);

//          Send user1
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 117, 115, 101, 114, 49, 13, 10 }, stream));

            //Wait for password prompt - Look for hex value for password:
            Wait4Prompt("50-61-73-73-77-6F-72-64-3A-20", stream);                    
//          Send pass1
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 112, 97, 115, 115, 49, 13, 10 }, stream));
//          Send pass1
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 112, 97, 115, 115, 49, 13, 10 }, stream));

//         Wait for last login message - Look for hex value for last login:
            Wait4Prompt("4C-61-73-74-20-6C-6F-67-69-6E-3A-20", stream);
//          Send ./sync
            textBox2.AppendText(WriteNReadBuffer(new byte[] { 46, 47, 115, 121, 110, 99, 13, 10 }, stream));
            
            stream.Close();
            client.Close(); 


        }
The data being sent to the stream are the decimal versions of the required telnet commands.
They are as follows:
First set of commands -
255 - Interpret as command (IAC) character
252 - WONT
24 - terminal type
255 - IAC
252 - WONT
31 - negotiate about window size
255 - IAC
252 - WONT
35 - x display location
255 - IAC
252 - WONT
39 - new environment option
255 - IAC
252 - WONT
36 - environment option

Second Set of commands -
255 - IAC
253 - DO
01 - echo
255 - IAC
253 - DO
03 - suppress go ahead

I am then waiting for "6C-6F-67-69-6E-3A-20\r\n" which is the hex equivalent of "login: "(there is also a CRLF on the end there)
6c - l
6F - o
67 - g
69 - i
6e - n
3a - :
\r - CR
\n - LF

When that's found I send the username "user1" and \r\n
117 - u
115 - s
101 - e
114 - r
49 - 1
13 - CR
10 - LR

Then I wait for password: to be found the same as I did login:
when that shows up I send my password which is the same as the user in this case. - user1 and \r\n.

As I mentioned above for some reason the server only seems to see the \r\n so I send the password again. This time I have better success.

Next I wait for "4C-61-73-74-20-6C-6F-67-69-6E-3A-20" which is "last login: "

Once I get that I can finally send my command to run the script on my server which is "./sync" in my case which I add the \r\n to again.

Next I close the stream and the client and am done.

I hope this helps you or someone else out.
blaramore is offline
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值