立即停止所有 SSH 连接
Stopping all SSH Connections at once
我正在开发一个程序,该程序应该与远程 Linux 服务器建立 "n" 多个 SSH 连接,并在每个连接上执行 运行 耗时的命令。 "time consuming operation" 基本上是 运行 设置 Wireshark 并侦听流量的脚本。
为此,我使用 C# 的 SharpSSH 库和 n 个 BackgroundWorker 作为线程。同样为了简单起见,下面的代码有 n=2 个 BGW 线程和 SSH 连接。
代码:
// runs when start is pressed
private void startButton_Click_1(object sender, EventArgs e)
{
sb = new StringBuilder();
DateTime timeNow = DateTime.Now;
clickTime = timeNow.ToString("yyyyMMddhhmmssfff"); // store the exact time of the click
bw = bwArray[0];
int index = 0; // ignore these 2 constants
foreach (BackgroundWorker bgw in bwArray)
{
if (bgw.IsBusy != true)
{
bgw.RunWorkerAsync();
// runWorkerAsync for every BackgroundWorker in the array
//index++;
}
}
}
// runWorkerAsync leads the BGWorker to this function
private void bw_doWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (worker.CancellationPending == true)
{
e.Cancel = true;
}
else
{
// let the UI know of button changes
int p = 0;
object param = "something"; // use this to pass any additional parameter back to the UI
worker.ReportProgress(p, param);
// UI notifying part ends here
// for the simplex case
if (numberOfConnections == 1)
startOperation();
// for the multiplex case
else if (numberOfConnections > 1)
{
//while (p < numberOfConnections)
//{
multiStartOperation();
// p++;
//}
}
Thread.Sleep(500);
}
}
// will be called for all ssh connections (in multiplex case)
private void multiStartOperation()
{
string[] command1Array = { "host2", "host2" };
string[] command2Array = { clickTime + "_h2", clickTime + "_h2" };
for (int index = 0; index < numberOfConnections; index++)
{
// shellArray is an array of SshExec objects
shellArray[index] = new SshExec(IPAddress, username, password);
try
{
shellArray[index].Connect();
}
catch (JSchException se)
{
Console.Write(se.StackTrace);
System.Windows.Forms.MessageBox.Show("Couldn't connect to the specified port.", "Connection Error!");
}
sb.Append(shellArray[index].RunCommand(command1Array[index]) + Environment.NewLine);
// first command is host3, or host4 etc.
// below is the time consuming command to run
string command = "./logcap.sh -c " + command2Array[index] + " -z";
// sb is a global stringBuilder object,
// to which the command output is appended
sb.Append(shellArray[index].RunCommand(command));
}
}
我的问题如下:
当我按下 GUI 上的启动按钮时,两个连接和 运行 脚本都应该启动。而在上面给出的代码中,shellArray(由 SshExec 对象组成)的第一个索引被连接,准备命令和 运行s 耗时的命令,此时程序返回到 UI,甚至没有开始第二个连接。这显然是因为 for 循环,但我还不知道如何解决这个问题。
我需要让另一个 backgroundworker 建立和 运行 第二个服务器的第二个命令,这样当我按下 GUI 上的停止按钮时,所有连接和线程都可以停止一起。
PS:命令不会停止 运行ning,除非用户单击停止,这会向服务器发送 Ctrl-C 信号。
我对所有多线程和网络概念都比较陌生,所以如果有任何混淆或错误请告诉我。
祝你有愉快的一天。
感谢您的回答,欢迎。 :)
问题确实是无法同时 运行 多个后台工作人员。
我设法解决了这个问题。事实证明,我只需要弄清楚如何将后台工作人员分配给 SSH 连接。为此,我创建了一个 class 如下:
class BGW
{
private BackgroundWorker bgw;
private int index;
//getters, setters, constructors...
}
在此之后,我将 bwArray(一个 BackgroundWorkers 数组)转换为一个 BGW 对象数组。在初始化时,我为每个 BGW 对象分配了一个索引。
我没有在 multiStartOperation() 中使用愚蠢的循环,而是向 multiStartOperation() 发送了一个整数参数,该函数使用该索引到达分配的后台工作程序。
到目前为止它似乎有效。
祝你有个愉快的一天。
我正在开发一个程序,该程序应该与远程 Linux 服务器建立 "n" 多个 SSH 连接,并在每个连接上执行 运行 耗时的命令。 "time consuming operation" 基本上是 运行 设置 Wireshark 并侦听流量的脚本。
为此,我使用 C# 的 SharpSSH 库和 n 个 BackgroundWorker 作为线程。同样为了简单起见,下面的代码有 n=2 个 BGW 线程和 SSH 连接。
代码:
// runs when start is pressed
private void startButton_Click_1(object sender, EventArgs e)
{
sb = new StringBuilder();
DateTime timeNow = DateTime.Now;
clickTime = timeNow.ToString("yyyyMMddhhmmssfff"); // store the exact time of the click
bw = bwArray[0];
int index = 0; // ignore these 2 constants
foreach (BackgroundWorker bgw in bwArray)
{
if (bgw.IsBusy != true)
{
bgw.RunWorkerAsync();
// runWorkerAsync for every BackgroundWorker in the array
//index++;
}
}
}
// runWorkerAsync leads the BGWorker to this function
private void bw_doWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (worker.CancellationPending == true)
{
e.Cancel = true;
}
else
{
// let the UI know of button changes
int p = 0;
object param = "something"; // use this to pass any additional parameter back to the UI
worker.ReportProgress(p, param);
// UI notifying part ends here
// for the simplex case
if (numberOfConnections == 1)
startOperation();
// for the multiplex case
else if (numberOfConnections > 1)
{
//while (p < numberOfConnections)
//{
multiStartOperation();
// p++;
//}
}
Thread.Sleep(500);
}
}
// will be called for all ssh connections (in multiplex case)
private void multiStartOperation()
{
string[] command1Array = { "host2", "host2" };
string[] command2Array = { clickTime + "_h2", clickTime + "_h2" };
for (int index = 0; index < numberOfConnections; index++)
{
// shellArray is an array of SshExec objects
shellArray[index] = new SshExec(IPAddress, username, password);
try
{
shellArray[index].Connect();
}
catch (JSchException se)
{
Console.Write(se.StackTrace);
System.Windows.Forms.MessageBox.Show("Couldn't connect to the specified port.", "Connection Error!");
}
sb.Append(shellArray[index].RunCommand(command1Array[index]) + Environment.NewLine);
// first command is host3, or host4 etc.
// below is the time consuming command to run
string command = "./logcap.sh -c " + command2Array[index] + " -z";
// sb is a global stringBuilder object,
// to which the command output is appended
sb.Append(shellArray[index].RunCommand(command));
}
}
我的问题如下:
当我按下 GUI 上的启动按钮时,两个连接和 运行 脚本都应该启动。而在上面给出的代码中,shellArray(由 SshExec 对象组成)的第一个索引被连接,准备命令和 运行s 耗时的命令,此时程序返回到 UI,甚至没有开始第二个连接。这显然是因为 for 循环,但我还不知道如何解决这个问题。
我需要让另一个 backgroundworker 建立和 运行 第二个服务器的第二个命令,这样当我按下 GUI 上的停止按钮时,所有连接和线程都可以停止一起。
PS:命令不会停止 运行ning,除非用户单击停止,这会向服务器发送 Ctrl-C 信号。
我对所有多线程和网络概念都比较陌生,所以如果有任何混淆或错误请告诉我。
祝你有愉快的一天。
感谢您的回答,欢迎。 :) 问题确实是无法同时 运行 多个后台工作人员。
我设法解决了这个问题。事实证明,我只需要弄清楚如何将后台工作人员分配给 SSH 连接。为此,我创建了一个 class 如下:
class BGW
{
private BackgroundWorker bgw;
private int index;
//getters, setters, constructors...
}
在此之后,我将 bwArray(一个 BackgroundWorkers 数组)转换为一个 BGW 对象数组。在初始化时,我为每个 BGW 对象分配了一个索引。
我没有在 multiStartOperation() 中使用愚蠢的循环,而是向 multiStartOperation() 发送了一个整数参数,该函数使用该索引到达分配的后台工作程序。
到目前为止它似乎有效。 祝你有个愉快的一天。