Put on the right path, tell me what can be done / read about it?

There is a list of objects of type IP.

class IP { public string host; public string login; public string password; } 

And the method that iterates through this list in a parallel loop, in which there is a connection to SSH.

 public void Cycle() { int port = 22; Parallel.ForEach(ipList, ipObject => { string ip = ipObject.host; string login = ipObject.login; string password = ipObject.password; SshConnect(ip, port, login, password); }); } 

The SSHConnect method SSHConnect implemented using the Renci.SSHNet library. As follows:

 private bool SshConnect(string host, int port, string login, string password) { bool flag = true; try { var client = new SshClient(host, port, login, password); client.Connect(); client.Disconnect(); } catch { flag = false; } return flag; } 

Everything would be fine, but the speed of searching and connecting to SSH is terribly slow. What can be done to increase the speed?

PS I used to have an algorithm that worked at least 2 times faster than this.

In it, I used one thread in which there was a loop, iterating the list, and in the same thread a certain number of other threads were created, which in turn processed these list items.

At another forum, they said that it was undesirable to do this and read a little, I decided to try Paralel.ForEach , but the result did not meet expectations.

  • language tag add - MolbOrg
  • Does the SshConnect() method SshConnect() have the ability to work in parallel threads? - The_Netos
  • I do not know. I just started learning parallel programming. How to define it? - Alexey

1 answer 1

When connecting via ssh, the main time is spent not by the processor, but by the network — the TCP SYN packet goes too long to the server and back. In such conditions, it is necessary and true to create as many streams as possible, Paralel.ForEach limits their number.


Do you have a list of ssh servers with which you need to do something - or do you scan the network?

In the second case, you can do optimization. First, you can check if port 22 is open - and then connect via ssh where it is open.

This can be done in parallel, but without threads, using asynchronous programming:

 var taskList = ipList.Select(async ipObject => { try { using (var c = new TcpClient()) await c.ConnectAsync(ipObject.host, 22); retrun ipObject; } catch { return null; } }).ToArray(); Task.WaitAll(taskList); ipList = taskList.Select(task => task.Result).Where(ipObject => ipObject != null).ToList(); // Теперь в ipList остались только хосты, которые отвечают на порту 22