C# SSH.Net 异步命令读取和写入



我正在尝试为某些路由器/交换机编写SSH脚本以使用 SSH.Net 读取信息。我想异步构建它,因为它们非常慢,延迟高。

我可以连接并发送命令,但是如果我尝试读出它,我只会得到一些空白行。如果我连续运行 7 次WriteLine()方法,我会看到 2 个预期的输出。我希望你能帮助我。

这是我的代码:

private static string _srv = "255.255.255.255";
private static string _usr = "looping";
private static string _pwd = "louie";
static void Main(string[] args)
{
GetDslamData();
Console.ReadKey();
}
private static async void GetDslamData()
{
using (SshClient _ssh = new SshClient(_srv, _usr, _pwd))
{
try
{
_ssh.Connect();
if (_ssh.IsConnected)
{
ShellStream stream = _ssh.CreateShellStream("mainstream", 0, 0, 0, 0, 2048);
if (stream.CanWrite)
{
stream.WriteLine("help");
}
if (stream.CanRead)
{
byte[] buffer = new byte[2048];
int i = 0;
if ((i = await stream.ReadAsync(buffer, 0, buffer.Length)) != 1)
{
Console.WriteLine(_ssh.ConnectionInfo.Encoding.GetString(buffer, 0, i));
}
}
}
_ssh.Disconnect();
_ssh.Dispose();
}
catch (Exception ex)
{
Console.WriteLine("Verbindungsfehler! Es konnte keine SSH-Session gestartet werden.");
}
}
}

首先,你要释放_ssh两次;一次是显式的,然后是当你离开using()范围时再次隐式的——你应该删除第一个。

其次,因为你没有等待GetDslamData()所以你在GetDslamData()继续奔跑的同时直接进入Console.ReadKey()。 虽然Console的大部分内容都是线程安全的,但至少有一些报告表明,在ReadKey()中执行WriteLine()会导致死锁或其他不受欢迎的行为;例如:

Console.ReadKey() 与多线程的奇怪行为

http://putridparrot.com/blog/console-readkey-and-console-writeline-deadlock/

从多个线程调用控制台.WriteLine

因此,请将您的GetDslamData()签名更改为以下内容:

private static async Task GetDslamData()

Main()这一点:

static void Main(string[] args)
{
GetDslamData().GetAwaiter().GetResult();
Console.ReadKey();
}

或者,如果您使用的是 C# 7.1+,请执行以下操作:

static async Task Main(string[] args)
{
await GetDslamData();
Console.ReadKey();
}

这样ReadKey()GetDslamData()完成之前不会执行。 如果您只有ReadKey(),因为您注意到您的应用程序会立即退出,请在更改上述代码后将其删除即可。