C#SSH.Net异步命令读写 [英] C# SSH.Net asynchronous command read and write

查看:58
本文介绍了C#SSH.Net异步命令读写的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为某些路由器/交换机编写SSH脚本,以使用SSH.Net读出信息.我想以异步方式构建它,因为它们的响应速度非常慢,并且延迟很高.

I am trying to write an SSH script for some routers/switches to read out information using SSH.Net. I want to build it asynchronous because they are pretty slow with high latency.

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

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. I hope you can help me.

这是我的代码:

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()范围时再次隐式-应该删除第一个.

First, you're disposing _ssh twice; once explicitly, then again implicitly when you leave the using() scope - you should drop the first one.

第二,因为您不等待 GetDslamData(),而是直接进入 Console.ReadKey(),而 GetDslamData()>继续运行.尽管大多数 Console 是线程安全的,但至少有一些报告称在 ReadKey()中执行 WriteLine()会导致死锁或其他不受欢迎的行为;例如:

Second, because you're not awaiting GetDslamData() you're dropping straight through to Console.ReadKey() while GetDslamData() keeps running. 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; e.g.:

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

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

从多个线程调用Console.WriteLine

因此,改为将您的 GetDslamData()签名更改为此:

So instead, change your GetDslamData() signature to this:

private static async Task GetDslamData()

Main()对此:

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

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

or if you are using C# 7.1+, to this:

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

那样,直到完成 GetDslamData()完成后,才会执行 ReadKey().如果您仅在其中有 ReadKey(),因为您注意到应用程序否则立即退出,请在按上述方法更改代码后将其删除.

That way ReadKey() won't be executed until GetDslamData() is complete. 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.

这篇关于C#SSH.Net异步命令读写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆