C# SSH.Net asynchronous command read and write

[亡魂溺海] 提交于 2021-02-08 07:23:02

问题


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.

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.

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

回答1:


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

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.:

Strange behaviour of Console.ReadKey() with multithreading

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

Calling Console.WriteLine from multiple threads

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

private static async Task GetDslamData()

and Main() to this:

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

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

static async Task Main(string[] args)
{
    await GetDslamData();
    Console.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.



来源:https://stackoverflow.com/questions/48808074/c-sharp-ssh-net-asynchronous-command-read-and-write

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!