如何检查Linux上的网络端口是否打开?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19196105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if a network port is open on linux?
提问by Fatima
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?
我如何知道某个端口在 linux ubuntu 上是否打开/关闭,而不是使用 python 的远程系统?如何在 python 中列出这些开放端口?
- Netstat: Is there a way to integrate netstat output with python?
- Netstat:有没有办法将 netstat 输出与 python 集成?
回答by mrjandro
You can using the socket moduleto simply check if a port is open or not.
您可以使用socket 模块来简单地检查端口是否打开。
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()
回答by Netch
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.
Netstat 工具只是解析一些 /proc 文件,如 /proc/net/tcp 并将其与其他文件内容结合起来。是的,它是高度特定于平台的,但对于仅限 Linux 的解决方案,您可以坚持使用它。Linux 内核文档详细描述了这些文件,因此您可以在那里找到如何阅读它们。
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.
另请注意,您的问题过于含糊,因为“端口”也可能表示串行端口(/dev/ttyS* 和类似物)、并行端口等;我重用了另一个答案的理解,这是网络端口,但我会要求您更准确地提出您的问题。
回答by Joe
If you only care about the local machine, you can rely on the psutil package. You can either:
如果你只关心本地机器,你可以依靠 psutil 包。您可以:
Check all ports used by a specific pid:
proc = psutil.Process(pid) print proc.connections()
Check all ports used on the local machine:
print psutil.net_connections()
检查特定 pid 使用的所有端口:
proc = psutil.Process(pid) print proc.connections()
检查本地机器上使用的所有端口:
print psutil.net_connections()
It works on Windows too.
它也适用于 Windows。
回答by Pitto
Just added to mrjandro's solution a quick hack to get rid of simple connection errors / timeouts.
刚刚在 mrjandro 的解决方案中添加了一个快速破解来摆脱简单的连接错误/超时。
You can adjust the threshold changing max_error_count variable value and add notifications of any sort.
您可以调整阈值更改 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()
And here you find a Python 3 compatible version (just fixed print syntax):
在这里你可以找到一个 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()
回答by Michael
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"
回答by Brent Kinser
For me the examples above would hang if the port wasn't open. Line 4 shows use of settimeoutto prevent hanging
对我来说,如果端口没有打开,上面的例子就会挂起。第 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)
回答by Alexander Turenko
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.
如果您探测 TCP 端口并打算侦听它,最好实际调用侦听。使用 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
回答by Hadi
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:
请检查迈克尔的回答并投票。这是检查开放端口的正确方法。如果您正在开发服务或守护程序,则 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
回答by CONvid19
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)
回答by hansaplast
Building upon the psutil
solution mentioned by Joe (only works for checking local ports):
基于psutil
Joe 提到的解决方案(仅适用于检查本地端口):
import psutil
1111 in [i.laddr.port for i in psutil.net_connections()]
returns True
if port 1111 currently used.
True
如果当前使用端口 1111,则返回。
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
psutil
不是 python stdlib 的一部分,所以你需要pip install psutil
首先。它还需要 python 头文件可用,所以你需要像python-devel