使用 Renci.SshNet 通过 ssh 连接读取输出流
Read in output stream through ssh connection using Renci.SshNet
我看过很多其他的堆栈溢出帖子,但 none 其中确实与我想要完成的相似。基本上,我试图通过 SSH 连接连接到设备 运行 Windows CE,并捕获打印到终端的任何输出。当我使用 Putty 通过 ssh 连接时,我可以在终端中看到许多用于调试的打印语句。我正在尝试捕获这些调试语句并在我的 wpf 应用程序中使用它们。这些调试语句不是对命令的响应,它们只是打印到终端。
到目前为止,我能够发送命令并收到单个响应,但我正在寻找的是能够无限期地接收响应,直到用户关闭连接或应用程序。
我正在使用 Renci.SshNet 发送我的命令,但我一直在使用 ShellStream,但无法使其正常工作。这是我目前所拥有的:
using System;
using System.Threading;
using System.Windows;
using Renci.SshNet;
namespace TestSshConsole
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private SshClient _sshConnection;
private ShellStream _shellStream;
private delegate void UpdateTextCallback(string message);
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// When the user presses connect, connect to the device
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
// Connect to device
_sshConnection = new SshClient(hostname.Text, int.Parse(port.Text), username.Text, password.Text);
_sshConnection.Connect();
// Create a shell stream
_shellStream = _sshConnection.CreateShellStream("test", 80, 60, 800, 600, 65536);
MessageBox.Show("Connected!");
}
catch (Exception exception)
{
MessageBox.Show($"Error {exception.Message}");
}
}
/// <summary>
/// Start a new thread used to receive SSH data when the window is loaded
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ThreadStart threadStart = new ThreadStart(RecvSshData);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// Receive SSH data and write it to the textbox
/// </summary>
private void RecvSshData()
{
while (true)
{
try
{
if (_shellStream != null && _shellStream.DataAvailable)
{
string data = _shellStream.Read();
textBox.Dispatcher.Invoke(new UpdateTextCallback(UpdateText), data);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Thread.Sleep(200);
}
}
/// <summary>
/// Write message to the textbox
/// </summary>
/// <param name="message"></param>
private void UpdateText(string message)
{
textBox.AppendText(message + "\r\n");
}
}
}
从我在其他帖子中读到的内容来看,这似乎应该有效并且应该捕获所有数据,但它没有。我在实施过程中可能做错了什么,或者他们甚至可能是更好的方法。
欢迎提供任何帮助或建议。
我在一定程度上让它发挥了作用。 "StartRecording" 开始在一个单独的线程上记录流,该线程现在可以将其写入控制台。这能够接收打印到我设备上的终端的所有数据。
我现在遇到的唯一问题是数据在大约一分钟后停止传输。我不确定发生了什么,但我认为 ShellStream 在某个时候断开连接,我不确定为什么。
private SshClient _sshClient;
private ShellStream _shellStream;
private StreamReader _reader;
private StreamWriter _writer;
public Recorder()
{
try
{
_sshClient = new SshClient(_hostname, _port, _username, _password);
_sshClient.Connect();
_shellStream = _sshClient.CreateShellStream("Terminal", 80, 60, 800, 600, 65536);
_reader = new StreamReader(_shellStream, Encoding.UTF8, true, 1024, true);
_writer = new StreamWriter(_shellStream) { AutoFlush = true };
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
}
/// <summary>
/// Begin recording the output of "routediagnostic on" command
/// </summary>
public void StartRecording()
{
try
{
IsRecording = true;
WriteStream("routediagnostic on");
// Start a background thread that will read in the data from the Pyng terminal
ThreadStart threadStart = ReceiveData;
Thread thread = new Thread(threadStart) {IsBackground = true};
thread.Start();
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
finally
{
IsRecording = false;
}
}
private void ReceiveData()
{
while (true)
{
try
{
if (_reader != null)
{
StringBuilder result = new StringBuilder();
string line;
while ((line = _reader.ReadLine()) != null)
{
result.AppendLine(line);
}
if (!string.IsNullOrEmpty(result.ToString()))
{
// TODO - Parse data at this point
Console.WriteLine(result.ToString());
}
}
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
Thread.Sleep(200);
}
}
private void WriteStream(string cmd)
{
_writer.WriteLine(cmd);
while (_shellStream.Length == 0)
{
Thread.Sleep(500);
}
}
我看过很多其他的堆栈溢出帖子,但 none 其中确实与我想要完成的相似。基本上,我试图通过 SSH 连接连接到设备 运行 Windows CE,并捕获打印到终端的任何输出。当我使用 Putty 通过 ssh 连接时,我可以在终端中看到许多用于调试的打印语句。我正在尝试捕获这些调试语句并在我的 wpf 应用程序中使用它们。这些调试语句不是对命令的响应,它们只是打印到终端。
到目前为止,我能够发送命令并收到单个响应,但我正在寻找的是能够无限期地接收响应,直到用户关闭连接或应用程序。
我正在使用 Renci.SshNet 发送我的命令,但我一直在使用 ShellStream,但无法使其正常工作。这是我目前所拥有的:
using System;
using System.Threading;
using System.Windows;
using Renci.SshNet;
namespace TestSshConsole
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private SshClient _sshConnection;
private ShellStream _shellStream;
private delegate void UpdateTextCallback(string message);
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// When the user presses connect, connect to the device
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
// Connect to device
_sshConnection = new SshClient(hostname.Text, int.Parse(port.Text), username.Text, password.Text);
_sshConnection.Connect();
// Create a shell stream
_shellStream = _sshConnection.CreateShellStream("test", 80, 60, 800, 600, 65536);
MessageBox.Show("Connected!");
}
catch (Exception exception)
{
MessageBox.Show($"Error {exception.Message}");
}
}
/// <summary>
/// Start a new thread used to receive SSH data when the window is loaded
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ThreadStart threadStart = new ThreadStart(RecvSshData);
Thread thread = new Thread(threadStart);
thread.IsBackground = true;
thread.Start();
}
/// <summary>
/// Receive SSH data and write it to the textbox
/// </summary>
private void RecvSshData()
{
while (true)
{
try
{
if (_shellStream != null && _shellStream.DataAvailable)
{
string data = _shellStream.Read();
textBox.Dispatcher.Invoke(new UpdateTextCallback(UpdateText), data);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Thread.Sleep(200);
}
}
/// <summary>
/// Write message to the textbox
/// </summary>
/// <param name="message"></param>
private void UpdateText(string message)
{
textBox.AppendText(message + "\r\n");
}
}
}
从我在其他帖子中读到的内容来看,这似乎应该有效并且应该捕获所有数据,但它没有。我在实施过程中可能做错了什么,或者他们甚至可能是更好的方法。
欢迎提供任何帮助或建议。
我在一定程度上让它发挥了作用。 "StartRecording" 开始在一个单独的线程上记录流,该线程现在可以将其写入控制台。这能够接收打印到我设备上的终端的所有数据。
我现在遇到的唯一问题是数据在大约一分钟后停止传输。我不确定发生了什么,但我认为 ShellStream 在某个时候断开连接,我不确定为什么。
private SshClient _sshClient;
private ShellStream _shellStream;
private StreamReader _reader;
private StreamWriter _writer;
public Recorder()
{
try
{
_sshClient = new SshClient(_hostname, _port, _username, _password);
_sshClient.Connect();
_shellStream = _sshClient.CreateShellStream("Terminal", 80, 60, 800, 600, 65536);
_reader = new StreamReader(_shellStream, Encoding.UTF8, true, 1024, true);
_writer = new StreamWriter(_shellStream) { AutoFlush = true };
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
}
/// <summary>
/// Begin recording the output of "routediagnostic on" command
/// </summary>
public void StartRecording()
{
try
{
IsRecording = true;
WriteStream("routediagnostic on");
// Start a background thread that will read in the data from the Pyng terminal
ThreadStart threadStart = ReceiveData;
Thread thread = new Thread(threadStart) {IsBackground = true};
thread.Start();
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
finally
{
IsRecording = false;
}
}
private void ReceiveData()
{
while (true)
{
try
{
if (_reader != null)
{
StringBuilder result = new StringBuilder();
string line;
while ((line = _reader.ReadLine()) != null)
{
result.AppendLine(line);
}
if (!string.IsNullOrEmpty(result.ToString()))
{
// TODO - Parse data at this point
Console.WriteLine(result.ToString());
}
}
}
catch (Exception e)
{
// TODO
Console.WriteLine(e);
}
Thread.Sleep(200);
}
}
private void WriteStream(string cmd)
{
_writer.WriteLine(cmd);
while (_shellStream.Length == 0)
{
Thread.Sleep(500);
}
}