c# - Windows 自动 telnet

标签 c# telnet tcpclient

我想运行一组通常在 telnet 中运行的命令(来自 c#)。

例如我想运行以下

using System;
using System.Diagnostics;

namespace InteractWithConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
            cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
            cmdStartInfo.RedirectStandardOutput = true;
            cmdStartInfo.RedirectStandardError = true;
            cmdStartInfo.RedirectStandardInput = true;
            cmdStartInfo.UseShellExecute = false;
            cmdStartInfo.CreateNoWindow = true;

            Process cmdProcess = new Process();
            cmdProcess.StartInfo = cmdStartInfo;
            cmdProcess.ErrorDataReceived += cmd_Error;
            cmdProcess.OutputDataReceived += cmd_DataReceived;
            cmdProcess.EnableRaisingEvents = true;
            cmdProcess.Start();
            cmdProcess.BeginOutputReadLine();
            cmdProcess.BeginErrorReadLine();

            cmdProcess.StandardInput.WriteLine("telnet telehack.com");
            int milliseconds = 2000;
            System.Threading.Thread.Sleep(milliseconds);
            cmdProcess.StandardInput.WriteLine("exit");

            cmdProcess.StandardInput.WriteLine("exit");
            cmdProcess.WaitForExit();
        }

        static void cmd_DataReceived(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data);
        }

        static void cmd_Error(object sender, DataReceivedEventArgs e)
        {
            Console.WriteLine(e.Data);
        }
    }
}

并保持 telnet 打开以运行后续命令。例如,对于上面的问题,我想运行并接收以下输出,但我没有收到任何 telnet 输出。它没有收到任何输出。 This is related.

telnet telehack.com
> Connected to TELEHACK port 53

It is 2:33 pm on Tuesday, September 1, 2015 in Mountain View, California, USA.
There are 31 local users. There are 24906 hosts on the network.

May the command line live forever.

Command, one of the following:
  ?           ac          advent      basic       cal         calc
  ching       clear       clock       cowsay      date        echo
  eliza       factor      figlet      finger      fnord       geoip
  help        hosts       ipaddr      joke        login       md5
  morse       newuser     notes       octopus     phoon       pig
  ping        primes      privacy     rain        rand        rfc
  rig         roll        rot13       sleep       starwars    traceroute
  units       uptime      usenet      users       uumap       uupath
  uuplot      weather     when        zc          zork        zrun
.calc
calc>2+2
> 4

最佳答案

根据评论,我了解到您可以使用实际的 telnet 协议(protocol)实现而不是调用 telnet.exe,所以

Form1.cs

using MinimalisticTelnet;
using System;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace Telnet
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private MinimalisticTelnet.TelnetConnection _tc;

        private void Form1_Load(object sender, EventArgs e)
        {
            _tc = new TelnetConnection("telehack.com", 23);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            ProcessOutput();
        }

        private void btnSendCommand_Click(object sender, EventArgs e)
        {
            if (_tc.IsConnected)
            {
                _tc.WriteLine(tbCommand.Text.Trim());
                tbCommand.Clear();
                tbCommand.Focus();
                ProcessOutput();
            }
        }

        private void ProcessOutput()
        {
            if (!_tc.IsConnected)
                return;

            var s = _tc.Read();
            s = Regex.Replace(s, @"\x1b\[([0-9,A-Z]{1,2}(;[0-9]{1,2})?(;[0-9]{3})?)?[m|K]?", "");
            tbOutput.AppendText(s);
        }
    }
}

Telnet接口(interface).cs

// minimalistic telnet implementation
// conceived by Tom Janssens on 2007/06/06  for codeproject
//
// http://www.corebvba.be



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

namespace MinimalisticTelnet
{
    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 string Login(string Username, string Password, int LoginTimeOutMs)
        {
            int oldTimeOutMs = TimeOutMs;
            TimeOutMs = LoginTimeOutMs;
            string s = Read();
            if (!s.TrimEnd().EndsWith(":"))
                throw new Exception("Failed to connect : no login prompt");
            WriteLine(Username);

            s += Read();
            if (!s.TrimEnd().EndsWith(":"))
                throw new Exception("Failed to connect : no password prompt");
            WriteLine(Password);

            s += Read();
            TimeOutMs = oldTimeOutMs;
            return s;
        }

        public void WriteLine(string cmd)
        {
            Write(cmd + Environment.NewLine);
        }

        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;
                }
            }
        }
    }
}

这是带有 2 个文本框和 1 个按钮以及一个计时器(间隔为 1000 毫秒)的 Windows 窗体应用程序。 我使用了 CodeProject 中的代码(链接在原始问题中)并进行了一些更改以使其实际工作。

关于c# - Windows 自动 telnet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32341057/

相关文章:

json - 通过 TELNET 发布一些 JSON

c# - 从 C# 中的 Process.Start 启动 cmd.exe 时,Telnet 无法识别命令

c# - 如何从远程服务器远程登录 - C#

c# - 如何在 C# 中动态调用构造函数?

c# - IDesignTimeDbContextFactory 并不总是需要的?

Java套接字: how to skip reading line from server when no output is sent from the server

python - 通过 Pi 与 python 之间的套接字通信 (TCP/IP) 发送传感器数据

c# - TcpClient - 现有连接被远程主机强行关闭

c# - ??的用法运算符(空合并运算符)

c# - 只返回计数大于 X 的对象