简体   繁体   English

C#SSH.Net异步命令读写

[英]C# SSH.Net asynchronous command read and write

I am trying to write an SSH script for some routers/switches to read out information using SSH.Net. 我正在尝试为某些路由器/交换机编写SSH脚本,以使用SSH.Net读取信息。 I want to build it asynchronous because they are pretty slow with high latency. 我想以异步方式构建它,因为它们非常慢且具有高延迟。

I can connect and send a command, but if I try to read it out, I just get some blank lines. 我可以连接并发送命令,但是如果我尝试读出它,我只会得到一些空白行。 If I run the WriteLine() method like 7 times in a row, I see like 2 of the expected outputs. 如果我连续7次运行WriteLine()方法,那么我将看到2个预期的输出。 I hope you can help me. 我希望你能帮助我。

Here is my code: 这是我的代码:

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

First, you're disposing _ssh twice; 首先,您要处理_ssh两次; once explicitly, then again implicitly when you leave the using() scope - you should drop the first one. 一次显式,然后在离开using()范围时再次隐式-应该删除第一个。

Second, because you're not awaiting GetDslamData() you're dropping straight through to Console.ReadKey() while GetDslamData() keeps running. 其次,由于您不等待GetDslamData() ,因此直接进入Console.ReadKey()GetDslamData()保持运行。 While much of Console is thread safe, there are at least some reports of performing WriteLine() while in a ReadKey() causing deadlocks or other unwelcome behaviour; 尽管大多数Console都是线程安全的,但至少有一些报告表明在ReadKey()中执行WriteLine()会导致死锁或其他不受欢迎的行为; eg: 例如:

Strange behaviour of Console.ReadKey() with multithreading 具有多线程的Console.ReadKey()的奇怪行为

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

Calling Console.WriteLine from multiple threads 从多个线程调用Console.WriteLine

So instead, change your GetDslamData() signature to this: 因此,改为将您的GetDslamData()签名更改为:

private static async Task GetDslamData()

and Main() to this: Main()

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

or if you are using C# 7.1+, to this: 或者,如果您使用的是C#7.1+,请执行以下操作:

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

That way ReadKey() won't be executed until GetDslamData() is complete. 这样ReadKey()之前,不会被执行GetDslamData()完成。 If you only had the ReadKey() there because you noticed your app was otherwise exiting immediately, just drop it after changing the code as above. 如果您仅在其中ReadKey() ,因为您注意到应用程序否则会立即退出,请在更改上述代码后将其删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM