C#SSH.Net异步命令读写

时间:2018-02-15 13:08:05

标签: c# asynchronous ssh async-await

我正在尝试为某些路由器/交换机编写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.");
        }
    }
}




1 个答案:

答案 0 :(得分:0)

首先,你要处理_ssh两次;一旦明确,然后当你离开using()范围时再次隐含 - 你应该放弃第一个。

其次,因为您没有等待GetDslamData(),所以当Console.ReadKey()一直运行时,您会直接转到GetDslamData()。虽然Console的大部分都是线程安全的,但至少有一些报告在WriteLine()导致死锁或其他不受欢迎的行为时执行ReadKey(); 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

相反,请将您的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(),因为你发现你的应用程序正在立即退出,只需在更改上面的代码后删除它。