gpt4 book ai didi

c# - SSH.NET 库 - SshClient.Dispose(),公共(public)连接

转载 作者:太空宇宙 更新时间:2023-11-03 21:28:59 27 4
gpt4 key购买 nike

我在使用 SSH.NET 库时遇到了 2 个问题。

我想创建 SSH 连接然后断开连接。但是如果我开始异步读取,断开连接会导致问题。当我尝试结束连接时,我的程序就死机了。

public void button1_Click(object sender, EventArgs e)
{
var ssh = new SshClient(IP, UserName, Password);

ssh.Connect();

var stream = ssh.CreateShellStream("anything", 80, 24, 800, 600, 4096);

byte[] buffer = new byte[1000];

stream.BeginRead(buffer, 0, buffer.Length, null, null);

stream.DataReceived += new EventHandler<Renci.SshNet.Common.ShellDataEventArgs>(
(s, ex) =>
{
Invoke((MethodInvoker)delegate
{
textBox1.AppendText(stream.Read());
});
}
);

stream.WriteLine("ls");

stream.Dispose();
ssh.Disconnect(); //problem here
}

我也不知道如何在代码中的任何地方创建一个可用的连接。我希望能够定义 IP、用户名和密码(例如,将它们写在一些文本框中),建立连接,然后通过执行一些命令并获取输入与其进行交互。据我所知,传递凭据需要一些事件处理程序(例如 button1_Click),但是如果我想通过传递命令与创建的 stream = ssh.CreateShellStream(...) 进行交互,例如button2_Click,我不能那样做,因为“当前上下文中不存在名称“stream””。

之前我一直在用 plik(来自 PuTTY)和 C# 的 Process 功能来做这件事:

private void ConnectButton_Click(object sender, EventArgs e)
{
...
p = new Process();
...
sw = p.StandardInput;
...
}

其中 sw 是在 ConnectButton_Click 事件处理程序之外定义的流编写器。

谢谢。

最佳答案

这是一个僵局。 button1_Click 正在您的 UI 线程上运行,DataReceived 中的 Invoke 也是如此。

SSH.NET 内部不使用异步——它的所有“异步”方法只是将同步方法包装在线程池中并锁定。

流程是这样的:

  1. BeginRead 捕获锁并开始阅读。
  2. Disconnect 在 UI 线程中等待锁定,直到“BeginRead 完成”。
  3. BeginRead 完成读取,并调用 DataReceived,后者调用 Invoke,同时仍持有锁。
  4. Invoke 等待 UI 线程处理它的消息 -- 但它永远不会,因为 UI 线程正在等待 Disconnect
  5. 现在 BeginReadDisconnect 都在等待彼此完成 - 一个死锁。

测试此问题的一种快速方法是将 Invoke 调用更改为 BeginInvoke,这将消除死锁。

就从您的 Form 中的任何位置访问这些对象而言,只需将它们设为该类的成员即可。

关于c# - SSH.NET 库 - SshClient.Dispose(),公共(public)连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25230255/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com