1

I'm creating a small tool which let me to check status of ports of given IP and port number like this:

private void ScanPort(IPAddress address, int port)
{
    using (TcpClient client = new TcpClient())
    {
        try
        {
            client.Connect(address, port);
            txtDisplay.AppendText("Port: " + nudFrom.Value.ToString() + 
                " is open." + Environment.NewLine);
        }
        catch (SocketException)
        {
            txtDisplay.AppendText("Port: " + nudFrom.Value.ToString() +
                " is closed." + Environment.NewLine);
        }
    }
}

The problem is that when port is open it takes about a second to check and if port is closed the process takes about 20 seconds time.

How to make checking for open/closed ports quicker?

HelpNeeder
  • 6,383
  • 24
  • 91
  • 155
  • Because throwing and catching exceptions is slow. If you can avoid using exceptions for control flow, you'll probably fix the speed issue. – Cody Gray - on strike Jan 24 '12 at 03:17
  • @Cody Gray, it does kind of help when port is open just to use client.connected but I'm not sure how to avoid try/catch since if port is closed it will throw an exception. – HelpNeeder Jan 24 '12 at 03:20

2 Answers2

2

One option would be to implement this using raw sockets in something like SharpPcap or Pcap.NET and catching the ICMP failure response. A simpler approach would be to look into reducing the timeout. Here's some ideas on how to do it. Here's a related question that might also help.

If you're strictly looking for ways to improve the performance of the code you posted then you may consider pinging the address prior to attempting to connect to it (assuming this is related to your prior question about ARP'ing remote hosts), and since String is immutable the + operator is generally slower than using something like String.Format. These suggestions will not cut seconds off your processing though (in fact you'll likely be unable to tell a difference).

Community
  • 1
  • 1
M.Babcock
  • 18,753
  • 6
  • 54
  • 84
  • I did find a reasonable answer on SO question you have suggested to look at. For now I'm trying to focus on IPs that I know are up and running and trying to work out just checking the ports. One question tho. I'm using the `result.AsyncWaitHandle.WaitOne(1000, true)` but I'm not sure what should I set the timeout to for reasonable respond time, what would you suggest? – HelpNeeder Jan 24 '12 at 04:04
  • That isn't the timeout I'm referring to. There is a socket connect timeout that will affect your performance as well. This is basically the amount of time your application waits for an ACK (I think that's the right one) packet before returning control to your application. You could benefit from running your connects async and only waiting as long as is appropriate for your application rather than waiting for the socket timeout. The first link provided includes an example of what I'm referring to. – M.Babcock Jan 24 '12 at 04:08
  • One way or another it points me into right direction. So basically I need to take a count for the timeout while trying to do any connections. Thanks m8. – HelpNeeder Jan 24 '12 at 04:16
1

I created a tool just like this to ping all IP Addresses on a network and get the response back.

I used the .net 4.0 parallel for / foreach features for this. It increased the performance dramatically.

tsells
  • 2,751
  • 1
  • 18
  • 20
  • @HelpNeeder - If you're looking for code you could try the little search box in the top right corner (http://stackoverflow.com/questions/2114266/convert-ping-application-to-multithreaded-version-to-increase-speed-c-sharp) – M.Babcock Jan 24 '12 at 13:20