How to check if a network port is open on linux?

廉价感情. 提交于 2019-12-17 17:28:44

问题


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?

回答1:


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()



回答2:


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"



回答3:


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)



回答4:


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




回答5:


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.




回答6:


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



回答7:


Just added to mrjandro's solution a quick hack to get rid of simple connection errors / timeouts.

You can adjust the threshold changing max_error_count variable value and add notifications of any sort.

import socket

max_error_count = 10

def increase_error_count():
    # Quick hack to handle false Port not open errors 
    with open('ErrorCount.log') as f:
        for line in f:
            error_count = line
    error_count = int(error_count)
    print "Error counter: " + str(error_count)
    file = open('ErrorCount.log', 'w')
    file.write(str(error_count + 1))
    file.close()
    if error_count == max_error_count:
        # Send email, pushover, slack or do any other fancy stuff
        print "Sending out notification"
        # Reset error counter so it won't flood you with notifications
        file = open('ErrorCount.log', 'w')
        file.write('0')
        file.close()

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

And here you find a Python 3 compatible version (just fixed print syntax):

import socket

max_error_count = 10

def increase_error_count():
    # Quick hack to handle false Port not open errors
    with open('ErrorCount.log') as f:
        for line in f:
            error_count = line
    error_count = int(error_count)
    print ("Error counter: " + str(error_count))
    file = open('ErrorCount.log', 'w')
    file.write(str(error_count + 1))
    file.close()
    if error_count == max_error_count:
        # Send email, pushover, slack or do any other fancy stuff
        print ("Sending out notification")
        # Reset error counter so it won't flood you with notifications
        file = open('ErrorCount.log', 'w')
        file.write('0')
        file.close()

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



回答8:


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



回答9:


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




回答10:


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



来源:https://stackoverflow.com/questions/19196105/how-to-check-if-a-network-port-is-open-on-linux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!