socket clientsocket available async c# telnet tcpclient

c# - clientsocket - Windows automatiza telnet



sockets tcp c# (3)

Me gustaría ejecutar un conjunto de comandos que normalmente se ejecutan en telnet (desde c #).

Por ejemplo me gustaría ejecutar el siguiente

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

y mantenga abierto telnet para ejecutar comandos subsiguientes. Por ejemplo, para la pregunta anterior, me gustaría ejecutar y recibir la siguiente salida, pero no recibo ninguna de las salidas de telnet. No recibe ninguna salida. Esto está relacionado.

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


Codificar esto puede ser difícil. Sin embargo, existen herramientas gratuitas para las secuencias de comandos de Telnet, consulte Expect por una. Si tiene una aplicación de C #, entonces su código podría generar el script Expect y luego ejecutar Expect?


Según los comentarios, entiendo que puede usar la implementación real del protocolo telnet en lugar de llamar a telnet.exe, por lo que

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

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

Esta es la aplicación de Windows Forms con 2 cuadros de texto, 1 botón y un temporizador (el intervalo es de 1000 ms). He usado código de CodeProject (vinculado en la pregunta original) con algunos cambios para que realmente funcione.


Enviar la información a telnet parece que debería ser sencillo; utilizar SendKeys() . La pregunta es cómo capturar la salida.

Encontré este video de YouTube que debería ayudar: https://www.youtube.com/watch?v=BDTCviA-5M8

La solución en el video no aborda realmente mantener la sesión abierta. Estoy un poco fuera de mi área de conocimiento aquí, pero creo que puedes iniciar telnet en un subproceso de trabajo, enviar comandos con SendKeys() , capturar la salida como se describe en el video y luego analizarla.

¿Eso resuelve suficientemente el requisito?