【问题标题】:C# SSH.Net asynchronous command read and writeC# SSH.Net 异步命令读写
【发布时间】:2018-07-26 06:13:05
【问题描述】:

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

【问题讨论】:

    标签: c# asynchronous ssh async-await


    【解决方案1】:

    首先,您要处理两次_ssh;一次显式,然后在您离开 using() 范围时再次隐式 - 您应该删除第一个。

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

    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(),因为您注意到您的应用程序会立即退出,请在更改上述代码后将其删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 2011-05-28
      • 2011-10-31
      • 1970-01-01
      • 2010-09-14
      • 2011-01-23
      • 2015-08-24
      相关资源
      最近更新 更多