Link to home
Start Free TrialLog in
Avatar of LeighWardle
LeighWardleFlag for Australia

asked on

Can a Windows app programmatically tell if a Port is open?

Hi Experts,


I have a VB.NET app that need access to the Internet via Port 29750.


I have been asking customers to configure their firewall to access inbound and outbound TCP traffic on Port 29750.


Can I programmatically tell if the port is open (without trying to access websites etc.)?

Regards,
Leigh
Avatar of Daniel Pineault
Daniel Pineault

Can you not use

Dim testSocket As New System.Net.Sockets.TcpClient()

Open in new window

and then try to connect
testSocket.Connect(ip, port)

Open in new window

and code for exceptions.


So the customers are running the app within their network and it's connecting to port 29750 on some remote (outside their network) device?

If so, then they do not need to configure their firewalls for inbound traffic on that port (and most customers probably don't need to adjust their firewall at all unless everything outbound is blocked by default).

However, there is really no way to test without some kind of connection attempt. A workstation can't tell anything about any device other then itself without making a connection attempt. Daniel provided a good, simple example above.
So the customers are running the app within their network

@gr8gonzo - That's speculative at this point as this hasn't been addressed

I'm thinking WAN->LAN
Hi,

I will not recommend exception based checking when there are other alternatives available.

Please try this:
Public Shared Function IsPortInUse(ByVal port As Integer) As Boolean
        Dim inUse As Boolean = False
      Dim gProps As IPGlobalProperties = IPGlobalProperties.GetIPGlobalProperties()
      Dim endPoints As IPEndPoint() = gProps.GetActiveTcpListeners()

      For Each endPoint As IPEndPoint In endPoints

            If endPoint.Port = port Then
                inUse = True
                Exit For
            End If
        Next

        Return inUse
    End Function

Open in new window


Usage
        Console.WriteLine(IsPortInUse(80))

Open in new window


Regards,
Chinmay.
@kenfcamp - That's what I was trying to confirm. I was thinking LAN->WAN because the OP implied that direction twice:

"VB.NET app that need access to the Internet via Port 29750." ("to the Internet" = outbound)

"without trying to access websites" ("to access websites" = outbound)


...and also if he was setting up a listener, that part about trying to access websites wouldn't really make sense in any context, which is why I didn't suggest checking for local listeners.

However, I could totally be wrong anyway. (shrug) We'll see if he responds.

I will say that port 29750 is an odd one to use for a server port. After port 10,000 I just leave the rest alone for dynamic client port usage.
@chinmay - That only works if the VB.NET app is acting as the server/listener.
User generated image

@Jonathan: This is the output of my app - it only lists code that I posted with minor modifications, if my console app has 35 established TCP connections... I will be scared :)

PS: the 52.114.*.* are Microsoft teams connections, for example.
@chinmay - no, I'm saying that the output of your app is only relevant if the situation is that the VB.NET app is intended to listen on port 29750.

If the VB.NET app is supposed to connect to port 29750 on some remote device, and the OP is asking whether there's a way to test if it can make that connection, then it doesn't matter what is actively listening on the local PC.
Avatar of LeighWardle

ASKER

Sorry Experts, due to time zone difference, I have not seen your posts until now.

Let me clarify my requirements:

Our app needs to access a License Server via inbound and outbound TCP traffic on Port 29750.
Our app uses a third party DLL (provided by License Server author) to handle the connections to the License Server.
When a user first installs our App and runs it for the first time, typically the app will be blocked due to the port not being open.
Our third party software will just give an error, something like "unable to connect to License Server ".
That message does not tell the user why the app is being blocked - could it be because the port is not open or is there something else preventing the connection?

That's why I would like to programmatically tell if the port is open.

Hope this helps....







Hi Leigh,

Are you 100% certain that you need inbound TCP traffic on that port?

If the license server runs on port 29750, then you definitely need the firewall to allow outbound TCP traffic on port 29750.

However, your app -probably- does not hardcode the local client port. So it probably picks a random available local client port and then uses that for the communication with the license server.

The only reason you would need the firewall to allow inbound traffic on that port is if the app was hardcoding its own client port (again, that would be very weird and be prone to other weird errors if some other application happened to be using that port) or if the app was running its own server, as well, on that port.

But if that was the case, you'd probably run into bigger issues because of IPv4 NAT routing. Basically, if some remote device sent some new packet to your public IP on that port, which computer within the internal LAN gets it? You'd basically end up in a situation where only one person could run the app at a time (or at least during the licensing process).

So it would be -really- bizarre if you had to explicitly allow inbound traffic on port 29750. More likely than not, your app picks a random client source port (e.g. 12345), then connects to the remote licensing server on port 29750, and the firewall "manages" that communication so that when the data comes back through, it knows how to route that data back to your computer on port 12345.

And again, if that's the case, then there's nothing you can do here -without- making a connection attempt with a TCP client, because your computer only knows which of its -own- ports are available or not (which is what Chinmay's code shows you). It cannot tell if it can communicate with the license server without a connection attempt because there are many different things that could stop / prevent the connection. For example, the firewall might block it, or you might have a local proxy that blocks it, or you might have a firewall rule that routes all outbound traffic on that port to a different destination, or you might have an ISP that blocks it, or the license server might have a firewall that doesn't like your public IP, or DNS could be down, etc, etc, etc... None of those are root causes that a computer can determine on its own.

It's very much like examining your own driveway to be able to determine whether there are any road blockages or construction on any of the highways that you are planning to drive on. Your own driveway doesn't have any bearing or information on other roads. The only thing you can do is hop in your car and give it a test run.
Here's another example, using a screenshot from the CurrPorts application (which is basically a nice little GUI version of the netstat tool, available here: https://www.nirsoft.net/utils/cports.html):

User generated image
You'll see that Chrome is connecting to port 443 (HTTPS) on a bunch of different servers. However, the local port numbers are all over the place. Those local port numbers are the source ports, and the firewall knows how to route the response from that HTTPS request back to that particular port so that Chrome knows what to do with it.

If you have a working connection with the license server, you can also use Process Monitor (https://docs.microsoft.com/en-us/sysinternals/downloads/procmon) to analyze the request so you can verify / confirm that the destination port is 29750 but that the source port is random and is not port 29750.
ASKER CERTIFIED SOLUTION
Avatar of kenfcamp
kenfcamp
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial