How to check if a network port is open?

PythonPortNetstat

Python Problem Overview


How can I know if a certain port is open/closed on linux ubuntu, not a remote system, using python? How can I list these open ports in python?

  • Netstat: Is there a way to integrate netstat output with python?

Python Solutions


Solution 1 - Python

You can using the socket module to simply check if a port is open or not.

It would look something like this.

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
   print "Port is open"
else:
   print "Port is not open"
sock.close()

Solution 2 - Python

If you want to use this in a more general context, you should make sure, that the socket that you open also gets closed. So the check should be more like this:

import socket
from contextlib import closing
   
def check_socket(host, port):
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        if sock.connect_ex((host, port)) == 0:
            print("Port is open")
        else:
            print("Port is not open")

Solution 3 - Python

For me the examples above would hang if the port wasn't open. Line 4 shows use of settimeout to prevent hanging

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)                                      #2 Second Timeout
result = sock.connect_ex(('127.0.0.1',80))
if result == 0:
  print 'port OPEN'
else:
  print 'port CLOSED, connect_ex returned: '+str(result)



Solution 4 - Python

If you only care about the local machine, you can rely on the psutil package. You can either:

  1. Check all ports used by a specific pid:

    proc = psutil.Process(pid)
    print proc.connections()
    
  2. Check all ports used on the local machine:

    print psutil.net_connections()
    

It works on Windows too.

https://github.com/giampaolo/psutil

Solution 5 - Python

Here's a fast multi-threaded port scanner:

from time import sleep
import socket, ipaddress, threading

max_threads = 50
final = {}
def check_port(ip, port):
	try:
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
		#sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
		socket.setdefaulttimeout(2.0) # seconds (float)
		result = sock.connect_ex((ip,port))
		if result == 0:
			# print ("Port is open")
			final[ip] = "OPEN"
		else:
			# print ("Port is closed/filtered")
            final[ip] = "CLOSED"
		sock.close()
	except:
		pass
port = 80
for ip in ipaddress.IPv4Network('192.168.1.0/24'): 
	threading.Thread(target=check_port, args=[str(ip), port]).start()
	#sleep(0.1)

    # limit the number of threads.
    while threading.active_count() > max_threads :
	    sleep(1)

print(final)

Live Demo

Solution 6 - Python

In case when you probing TCP ports with intention to listen on it, it’s better to actually call listen. The approach with tring to connect don’t 'see' client ports of established connections, because nobody listen on its. But these ports cannot be used to listen on its.

import socket


def check_port(port, rais=True):
    """ True -- it's possible to listen on this port for TCP/IPv4 or TCP/IPv6
    connections. False -- otherwise.
    """
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('127.0.0.1', port))
        sock.listen(5)
        sock.close()
        sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
        sock.bind(('::1', port))
        sock.listen(5)
        sock.close()
    except socket.error as e:
        return False
        if rais:
            raise RuntimeError(
                "The server is already running on port {0}".format(port))
    return True

Solution 7 - Python

Agree with Sachin. Just one improvement, use connect_ex instead of connect, which can avoid try except

>>> def port_check(ip_port):
...     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...     s.settimeout(1)
...     return s.connect_ex(ip_port) == 0
... 
>>> port_check(loc)
True
>>> port_check(loc_x)
False
>>> loc
('10.3.157.24', 6443)
>>> 

Solution 8 - Python

Netstat tool simply parses some /proc files like /proc/net/tcp and combines it with other files contents. Yep, it's highly platform specific, but for Linux-only solution you can stick with it. Linux kernel documentation describes these files in details so you can find there how to read them.

Please also notice your question is too ambiguous because "port" could also mean serial port (/dev/ttyS* and analogs), parallel port, etc.; I've reused understanding from another answer this is network port but I'd ask you to formulate your questions more accurately.

Solution 9 - Python

I found multiple solutions in this post.But some solutions having a hanging issue or taking to much time in case of the port was not opened.Below solution worked for me :

import socket 

def port_check(HOST):
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.settimeout(2) #Timeout in case of port not open
   try:
      s.connect((HOST, 22)) #Port ,Here 22 is port 
      return True
   except:
      return False

port_check("127.0.1.1")

Solution 10 - Python

Just added to mrjandro's solution some improvements to get rid of simple connection errors / timeouts and print out results:

import socket
from contextlib import closing

hosts = ["host1", "host2", "host3"]
port = 22
timeout_in_seconds = 2

hosts_with_opened_port = []
hosts_with_closed_port = []
hosts_with_errors = []


def check_port(host, port, timeout_in_seconds):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(timeout_in_seconds)
    with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        try:
            result = sock.connect_ex((host, port))
            if result == 0:
                print("Port {} is *** OPEN *** on host: {}".format(port, host))
                hosts_with_opened_port.append(host)
            else:
                print("Port {} is not open on host: {}".format(port, host))
                hosts_with_closed_port.append(host)
        except socket.gaierror:
            print("Port {} check returns a network *** ERROR *** on host: {}".format(port, host))
            hosts_with_errors.append(host)


for host in hosts:
    check_port(host, port, timeout_in_seconds)

print("\nHosts with opened port:")
print(hosts_with_opened_port)
print("\nHosts with closed port:")
print(hosts_with_closed_port)
print("\nHosts with errors:")
print(hosts_with_errors)

Solution 11 - Python

Please check Michael answer and vote for it. It is the right way to check open ports. Netstat and other tools are not any use if you are developing services or daemons. For instance, I am crating modbus TCP server and client services for an industrial network. The services can listen to any port, but the question is whether that port is open? The program is going to be used in different places, and I cannot check them all manually, so this is what I did:

from contextlib import closing
import socket
class example:
    def __init__():
       
       self.machine_ip = socket.gethostbyname(socket.gethostname())
       self.ready:bool = self.check_socket()

    def check_socket(self)->bool:
        result:bool = True
        with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
        modbus_tcp_port:int = 502
        if not sock.connect_ex((self.machine_ip, modbus_tcp_port)) == 0:
            result = False
        return result

Solution 12 - Python

Building upon the psutil solution mentioned by Joe (only works for checking local ports):

import psutil
1111 in [i.laddr.port for i in psutil.net_connections()]

returns True if port 1111 currently used.

psutil is not part of python stdlib, so you'd need to pip install psutil first. It also needs python headers to be available, so you need something like python-devel

Solution 13 - Python

This will find a random port in the given range:

import socket
import random 
from typing import Tuple

def find_listening_port(
    port_range:Tuple[int,int]=None, 
    host='', 
    socket_type='tcp', 
    default:int=None
) -> int:
    """Find an available listening port
    
    Arguments:
        port_range: Optional tuple of ports to randomly search, ``[min_port, max_port]``
            If omitted, then randomly search between ``[6000, 65534]``
        host: Host interface to search, if omitted then bind to all interfaces
        socket_type: The socket type, this should be ``tcp`` or ``udp``
        default: The port to try first before randomly searching the port range

    Returns:
        Available port for listening
    """
    def _test_port(host, port, socket_protocol):
        with socket.socket(socket.AF_INET, socket_protocol) as sock:
            try:
                sock.bind((host, port))
                if socket_type == 'tcp':
                    sock.listen(1)
                return port
            except:
                pass 

        return -1

    if port_range is None:
        port_range = (6000,65534)

    if socket_type == 'tcp':
        socket_protocol = socket.SOCK_STREAM
    elif socket_type == 'udp':
        socket_protocol = socket.SOCK_DGRAM
    else:
        raise Exception('Invalid socket_type argument, must be: tcp or udp')

    searched_ports = []
    if default is not None:
        port = _test_port(host, default, socket_protocol)
        if port != -1:
            return port
        searched_ports.append(default)

    for _ in range(100):
        port = random.randint(port_range[0], port_range[1])
        if port in searched_ports:
            continue 

        port = _test_port(host, port, socket_protocol)
        if port != -1:
            return port

        searched_ports.append(port)

    raise Exception(f'Failed to find {socket_type} listening port for host={host}')

Example usage:

# Find a TCP port,
# first check if port 80 is availble
port = find_listening_port(
    port_range=(4000, 60000),
    host='',
    socket_type='tcp',
    default=80
)
print(f'Available TCP port: {port}')

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFatimaView Question on Stackoverflow
Solution 1 - PythonmrjandroView Answer on Stackoverflow
Solution 2 - PythonMichaelView Answer on Stackoverflow
Solution 3 - PythonBrent KinserView Answer on Stackoverflow
Solution 4 - PythonJoeView Answer on Stackoverflow
Solution 5 - PythonPedro LobitoView Answer on Stackoverflow
Solution 6 - PythonAlexander TurenkoView Answer on Stackoverflow
Solution 7 - PythonRenuka ManavalanView Answer on Stackoverflow
Solution 8 - PythonNetchView Answer on Stackoverflow
Solution 9 - PythonSachinView Answer on Stackoverflow
Solution 10 - PythonPittoView Answer on Stackoverflow
Solution 11 - PythonHadiView Answer on Stackoverflow
Solution 12 - PythonhansaplastView Answer on Stackoverflow
Solution 13 - PythondriedlerView Answer on Stackoverflow