How can I check the status of a given port on a remote host?

First, it's worth clarifying that by "status" we understand the question to be asking whether the port is open or not; that is, whether there is an application listening to that port. There are two cases to be considered, namely TCP and UDP.

TCP

For TCP ports, this is relatively straightforward: if an application is listening on the port, then the host will respond to a SYN packet arriving at that port with a corresponding SYN-ACK. There are many tools that we can use to try to establish a TCP connection, and here we will use curl, an open-source command-line tool for working with web-based interfaces:

https://curl.haxx.se/

It comes as standard in most Linux distributions, and is available for Windows too.

To check the status of TCP port 12345 on host 10.0.0.1, we use curl to attempt to establish a connection as follows:

$ curl 10.0.0.1:12345

We can expect one of the following three different outcomes:

  1. If curl exits immediately with the error
    curl: (7) Failed to connect to 10.0.0.1 port 12345: Connection refused
    
    then we know that the port is closed and no application is listening on it.
  2. If curl exits immediately without any error, or with an error such as
    curl: (52) Empty reply from server
    
    then we know that an application accepted the connection from curl, and either sent some content back to curl, or was confused by what curl sent it and closed the connection. In either case, we know the port is open with something listening on it.
  3. If curl hangs for a few minutes (typically 3 minutes) and then exits with
    curl: (7) Failed to connect to 10.0.0.1 port 12345: Connection timed out
    then we know that the port is not reachable from where we are running curl. This is most likely because of a firewall rule silently blocking our connection attempts, or perhaps a routing problem. In this case, we cannot determine the status of the port because we cannot even reach it.

Another possibility is that curl may simply hang indefinitely, if the port is open and the application listening on the port simply ignores the HTTP request that curl sends. To double-check whether this is happening, we would need to take a packet-capture of the connection attempt and see whether the three-way handshake was successful. However it is unlikely that a server listening on a port would behave this way.

UDP

For UDP ports, the process is quite similar, except that there is no standard timeout mechanism for failed UDP connections. UDP does not even implement any concept of a connection; instead a client can only send a request to the port in the expectation that a compatible server application has bound to that port to respond to it within some reasonable period of time.

Since curl does not support UDP, we will instead use socat, http://www.dest-unreach.org/socat/, an open-source utility that can establish many different kinds of connections, not just TCP or UDP, and bridge them in creative ways. Although socat is primarily a UNIX-based utility, it can be built for Windows too: https://github.com/StudioEtrange/socat-windows

To check the status of UDP port 12345 on host 10.0.0.1, we prompt socat to send a UDP packet by starting it up as follows and typing in a short message (the string "test") for it to send:

$ socat STDIO UDP-CONNECT:10.0.0.1:12345
test

Again, we can expect one of three different outcomes:

  1. If socat exits immediately with an error similar to
    2018/09/12 12:05:48 socat[6431] E read(5, 0x691130, 8192): Connection refused
    then we know that the port is closed and no application is listening on it.
  2. If socat outputs any kind of content in return, we know that some application on the port was listening and replied, so the port is open.
  3. If we get no response whatsoever within a few seconds, it is most likely that the port is not reachable, again either because of a firewall rule or network connectivity problem.

Again it is possible, but unlikely, that the port is open with an unresponsive application listening on it. Unfortunately there is no reliable way to distinguish between this case and a firewall silently blocking the communication.