I briefly had a problem with the web server that’s running my personal wiki yesterday. Try as I might it just wouldn’t start-up. I hadn’t had a problem before and after three or four attempts at clicking the start option I took a step back and surveyed my machine – a useful option in many circumstances.
I spotted the culprit straight away as I had come across the issue before – Skype. When Skype starts up if the default port (51907 on my current instance of Skype) is unavailable (because another application is using it or more likely a firewall is blocking it) it tries to set-up on a port that is more likely to be available – 80 or 443 which are used by web servers for insecure and secure traffic respectively.
Whilst there is an advanced option in Skype to force it away from these two alternative ports often there are no other convenient ones to choose from. This is because it is good practice security to block unused ports and Skype isn’t always a top runner so to speak on ports to have open.
The moral of the story is simple – start your web server before you start Skype.
However this got me to wondering what else might pick a port that could conflict and how would you know what it was without just systematically working through all the applications and services you have running … which for me could be a large number. My solution was to use some DOS commands. NETSTAT can be used to examine what ports are in use by what processes. TASKLIST can be used then to identify the executable.
To smooth things over a little I’ve concocted a little script to automate this process. It’s really just a bit of a nicer front end to the whole thing and whilst several command prompt windows may briefly flash up as it runs, the script will take in the information from the commands and process them to filter out the pertinent information.
Option Explicit Dim objCommandPort Dim astrResults Dim astrInfoLine Dim strOutput Dim strPortCommand Dim strPID Dim strApps strPortCommand = "netstat -ano" set objCommandPort = New clsDOSCommandExecutor objCommandPort.ExecuteCommand(strPortCommand) strOutput = objCommandPort.GetOutput astrResults = split(strOutput, vbCrLf) strApps = "PORT: APPLICATION" & vbCrLf AssessPort "80" strApps = strApps & vbCrLf AssessPort "443" MsgBox strApps, vbInformation + vbOKOnly, "Applications using web server ports" Sub AssessPort(p_strPort) Dim intCounter For intCounter = 1 to Ubound(astrResults) If inStr(astrResults(intCounter), ":" & p_strPort) > 0 Then astrInfoLine = split(astrResults(intCounter)) strPID = astrInfoLine(ubound(astrInfoLine)) strApps = strApps & vbCrLf & p_strPort & ": " & AppOnPort(strPID) End If Next End Sub Function AppOnPort(p_strPID) Dim objCommandPID Dim strPIDCommand Dim strPIDOut Dim astrPIDOut set objCommandPID = New clsDOSCommandExecutor strPIDCommand = "tasklist /fi ""PID eq " & p_strPID & """" objCommandPID.ExecuteCommand(strPIDCommand) strPIDOut = Right(objCommandPID.GetOutput, len(objCommandPID.GetOutput) - inStrRev(objCommandPID.GetOutput, "=" & vbcrlf)) astrPIDOut = split(strPIDOut) AppOnPort = Replace(astrPIDout(0), vbCrLf, "") End Function Class clsDOSCommandExecutor Dim objShell, objExec Dim strCommand Dim strError Dim objError Dim objOutput Dim strOutput Sub ExecuteCommand(p_strCommand) strCommand = "cmd /c " & p_strCommand Set objShell = CreateObject("Wscript.Shell" ) objShell.Exec(strCommand) Set objExec = objShell.Exec(strCommand) Do Until objExec.Status Wscript.Sleep 200 Loop Set objError = objExec.StdErr strError = objError.ReadAll Set objOutput = objExec.stdOut strOutput = objOutput.ReadAll End Sub Function GetOutput() GetOutput = strOutput End Function Function GetError() GetError = strError End Function Function Failed() If strError = "" Then Failed = false Else Failed = true End If End Function End Class