SSH, VB.NET and Multi-threading

I'll start with my question and a brief bio:

The question is, "Can anyone assist me in multi-threading this "

Bio: I'm still new to VB.NET. A while back, we had a need to create "something" that would SSH to multiple servers, run a command (or series of commands) and return the results. The code below is what I came up with.

In regards to the question I posed, this app runs on a server with multiple CPUs and plenty of horsepower. The application kicks off Plink which is a command line utility that comes with Putty. Works great...but, it is slow. When I say multiple servers...I'm talking about more than 15...it executes Plink.exe, runs the command, returns the results, executes Plink.exe, runs..., ..., ...

Adding the ability to use mulitple threads would greatly enhance this...but, as I noted, I got this far on basically hack credentials. Now, I would like to take it to the next level.

The code below is called from an aspx page, fed some varibales, and returns the results to the page.

I hope that with the lack of SSH info out there that maybe my post will help someone else looking to do the same thing, while answering my issue too!

ANY help would be appreciated!!!

R/

Jason Vaughn

'Begin searchnet.dll

Imports System
Imports System.IO
Imports System.Web
Imports System.Xml
Imports System.Text
Imports System.Data
Imports System.Threading
Imports System.Diagnostics
Imports Microsoft.VisualBasic

Namespace SearchNet

Public Class SearchData

Public strNow As String
Public allResults As String

Public Function DoTheSearch( strSearch As String,intLogLevel As Integer,strServerGroup As String,intQueryTimer As Integer )
Dim dtmNow As DateTime
dtmNow = DateTime.Now()
Dim usrname As String
Dim pw As String
Dim cfg As New XmlDataDocument
Dim adminCfg As New XmlDocument()
Dim ndList As XmlNodeList
Dim nd As XmlNode
Dim PlinkLocation As String
Dim LogFileLocation As String
Dim ServerConfigFileLocation As String
Dim TimeOutValue As Integer

adminCfg.Load(HttpContext.Current.Server.MapPath("./bin/searchnetadmin.config"))
Dim root As XmlNode = adminCfg.FirstChild
PlinkLocation = root("PlinkLocation").InnerText
LogFileLocation = root("LogFileLocation").InnerText
ServerConfigFileLocation = root("ServerConfigFileLocation").InnerText
strNow = dtmNow.ToString("MMddyyyyhhmmssfff")
cfg.Load( ServerConfigFileLocation & "\searchnet" & strServerGroup & ".config" )
ndList = cfg.SelectNodes("//ServerMenuItemInfo")

If strServerGroup = "farm1" or strServerGroup = "farm2" Then
usrname = "username1"
pw = "password1"
Else
usrname = "username2"
pw = "username2"
End If

For Each nd in ndList
Dim arrServerInfo As Array
Dim serverName As String
Dim serverIpAddress As String
Dim proc As Process = New Process()
Dim strPlinkArguments As String

arrServerInfo = Split(nd.InnerText,":")
serverName = arrServerInfo(0)
serverIpAddress = arrServerInfo(1)
strPlinkArguments = "-ssh -l " & usrname & " -pw " & pw & " " & usrname & "@" & serverIpAddress & " -batch "
proc.StartInfo.FileName = PlinkLocation
proc.StartInfo.Arguments = strPlinkArguments & strSearch
proc.StartInfo.UseShellExecute = False
proc.StartInfo.RedirectStandardOutput = True

Try
proc.Start()
Catch ex As Exception
'place holder for future use
End Try

Dim tmeNow As DateTime
Dim procStartTime As DateTime = proc.StartTime
Dim ts As TimeSpan
Dim timeOutMessage As String

Dim sr As StreamReader = proc.StandardOutput
Dim sb As New StringBuilder("")
Dim input As Integer = sr.Read

sb.Append("<hr>")
sb.Append("<strong>" & serverName & " - " & serverIpAddress & "</strong>")
sb.Append(Environment.NewLine)
sb.Append("<hr>")
Do Until input = -1
tmeNow = DateTime.Now()
sb.Append(ChrW(input))
input = sr.Read
ts = tmeNow.Subtract(procStartTime)
If ts.Seconds >= intQueryTimer Then
input = -1
timeOutMessage = "Query time exceeded " & intQueryTimer & " seconds. Please redefine your query."
Else
timeOutMessage = ""
End If
Loop
sb.Append(Environment.NewLine)
If timeOutMessage <> "" Then
sb.Append("<strong><font color=red>" & timeOutMessage & "</font></strong>")
sb.Append(Environment.NewLine)
End If
sb.Append("<strong>Query Time: = " & ts.Seconds & "." & ts.Milliseconds.ToString & " Seconds</strong>")
sb.Append(Environment.NewLine)

allResults = allResults + sb.ToString

sr.Close()
proc.Close()
Next

If intLogLevel = 1 Then
allResults = allResults + "File Name: searchnet" & strNow & ".txt"
Else
allResults = allResults
End If

If intLogLevel = 1 Then
Dim sw As New StreamWriter( LogFileLocation & "\searchnet" & strNow & ".txt")
sw.write(Replace(Replace(Replace(Replace(Replace(allResults,"<hr>",""),"<strong>",""),"</strong>",""),"</font>",""),"<font color=red>",""))
sw.Close()
End If

End Function

End Class

End Namespace



Answer this question

SSH, VB.NET and Multi-threading

  • Michelle A.

    new2vbdotnet,

    Don't forget to mark OmegaMan's answer as Answered after you have solved your problems.



  • JojoShow

    Thanks OmegaMan...I have researched the threading quandry...but, you have provided some new information. Off to read I go...

    J


  • David Nielsen

    Don't get hung up, no pun intended, on what the application is... Break it down into the components. First work on the connection for one with an eye in mind on thread safety. Then work on the threading.

    Since threading is the issue at hand, examples are the best way to learn. Check out the section Working with threads to manage multiple tasks simultaneously in the 101 Samples for Visual Studio 2005 . The examples are many from initial development tasks to more involved tasks for winforms, web development etc which may help you in other areas.

    Also check out Safe Thread Synchronization by Jeffrey Richtor to help you with threading topics.


  • SSH, VB.NET and Multi-threading