我如何使用python在Linux ubuntu而非远程系统上打开/关闭某个端口?如何在python中列出这些打开的端口?
- Netstat:有没有办法将netstat输出与python集成?
Answers:
您可以使用套接字模块简单地检查端口是否打开。
它看起来像这样。
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()
如果要在更一般的上下文中使用它,则应确保打开的套接字也已关闭。所以检查应该更像这样:
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"
connect_ex
代替bind
。我的所有尝试在py3和mac上使用connect或connect_ex的尝试均失败,并显示错误61,然后自动将端口分配给我的套接字,然后是err22。相反bind
,,执行我期望的操作,如果端口是打开,如果正在使用则扔。我想念什么吗?
对我来说,如果端口未打开,则上面的示例将挂起。第4行显示了使用settimeout防止挂起
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)
如果只关心本地计算机,则可以依赖psutil软件包。您可以:
检查特定pid使用的所有端口:
proc = psutil.Process(pid)
print proc.connections()
检查本地计算机上使用的所有端口:
print psutil.net_connections()
它也适用于Windows。
pip
而不是apt-get / yum)
如果您打算侦听TCP端口以进行侦听,最好实际调用listen。使用tring进行连接的方法不会“看到”已建立连接的客户端端口,因为没有人在监听它。但是这些端口不能用来侦听它。
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
这是一个快速的多线程端口扫描器:
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)
刚刚添加到mrjandro的解决方案中的是一种快速技巧,以摆脱简单的连接错误/超时。
您可以调整阈值,以更改max_error_count变量值,并添加各种通知。
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()
在这里,您可以找到与Python 3兼容的版本(只是固定的打印语法):
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()
请检查迈克尔的答案并投票。这是检查打开的端口的正确方法。如果您要开发服务或守护程序,则Netstat和其他工具将无用。例如,我正在为工业网络创建modbus TCP服务器和客户端服务。服务可以监听任何端口,但问题是该端口是否打开?该程序将在不同的地方使用,我无法手动检查它们,因此我做了以下操作:
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
在上面,我找到了多个解决方案。但是有些解决方案存在挂起问题,或者在打开端口的情况下花费很多时间。下面的解决方案对我有用:
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")
同意萨钦。只是一项改进,使用connect_ex而不是connect可以避免尝试,但
>>> def port_check(ip_port):
... s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
... s.settimeout(1)
... r = s.connect_ex(ip_port)
... return r == 0
...
>>> port_check(loc)
True
>>> port_check(loc_x)
False
>>> loc
('10.3.157.24', 6443)
>>>