我正在尝试为某些路由器/交换机编写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.");
}
}
}
首先,你要释放_ssh
两次;一次是显式的,然后是当你离开using()
范围时再次隐式的——你应该删除第一个。
其次,因为你没有等待GetDslamData()
所以你在GetDslamData()
继续奔跑的同时直接进入Console.ReadKey()
。 虽然Console
的大部分内容都是线程安全的,但至少有一些报告表明,在ReadKey()
中执行WriteLine()
会导致死锁或其他不受欢迎的行为;例如:
Console.ReadKey() 与多线程的奇怪行为
http://putridparrot.com/blog/console-readkey-and-console-writeline-deadlock/
从多个线程调用控制台.WriteLine
因此,请将您的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()
,因为您注意到您的应用程序会立即退出,请在更改上述代码后将其删除即可。