在Python中检查远程主机是否已启动

问题描述 投票:0回答:7

如何在没有端口号的情况下检查远程主机是否已启动?除了使用常规 ping 之外,还有其他方法可以检查吗?

远程主机可能会丢弃 ping 数据包

python network-programming network-protocols
7个回答
21
投票

这对我来说效果很好:

SOMEHOST = 'localhost'
HOST_UP  = os.system(f"ping -c 1 {SOMEHOST}") is 0

注:

  • 如评论中所述,
    SOMEHOST
    变量不应来自任何潜在的恶意输入。

3
投票

协议级 PING 是最好的,即连接到服务器并以不执行实际工作的方式与其交互。这是因为这是确保 service 正常运行的唯一真正方法。 ICMP ECHO(又名 ping)只会告诉您另一端的网络接口已启动,即使如此也可能被阻止; FWIW,我见过所有用户进程都被阻塞但仍然可以 ping 通的机器。在当今的应用程序服务器中,即使获得网络连接也可能不够。如果托管应用程序已关闭或无法运行怎么办?正如我所说,对您感兴趣的实际服务说些甜言蜜语是最好、最可靠的方法。


2
投票

许多防火墙配置为丢弃 ping 数据包而不响应。此外,某些网络适配器将在没有操作系统网络堆栈输入的情况下响应 ICMP ping 请求,这意味着操作系统可能已关闭,但主机仍会响应 ping(通常,如果您重新启动服务器,您会注意到,例如,它会在操作系统实际启动和其他服务启动之前的某个时间开始响应 ping)。

确定主机已启动的唯一方法是实际尝试通过一些众所周知的端口(例如 Web 服务器端口 80)连接到它。

为什么需要知道主机是否“启动”,也许有更好的方法来做到这一点。


2
投票
HOST_UP  = True if os.system("ping -c 5 " + SOMEHOST.strip(";")) is 0 else False

要删除讨厌的脚本执行,只需添加 .strip(";")

-c 5 

增加 ping 请求的数量,如果全部通过则为 True

PS。仅适用于 Linux,在 Windows 上始终返回 True


1
投票

你能做的最好的事情是:

许多站点都会阻止 ICMP(用于 ping 站点的端口),因此您必须事先知道相关主机是否启用了 ICMP。

连接到端口会告诉您混合信息。这实际上取决于您想知道什么。端口可能是开放的,但站点实际上已挂起,因此您可能会得到误报。更严格的方法可能涉及使用 HTTP 库对站点执行 Web 请求,并查看是否收到响应。

这实际上完全取决于您需要了解什么。


1
投票

尝试一些需要 RPC 的东西(例如“任务列表”命令与 ping 结合使用)怎么样?


1
投票

我会使用端口扫描仪。最初的问题表明您不想使用端口。然后您需要指定要监控的协议(是的,这需要端口):HTTP、VNC、SSH 等。如果您想通过 ICMP 进行监控,您可以使用子进程并控制 ping 参数、ping 数量、超时、尺寸等

import subprocess 
    try:
        res = subprocess.Popen(['ping -t2 -c 4 110.10.0.254 &> /dev/null; echo $?'],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        out, err = res.communicate()
        out = out.rstrip()
        err = err.rstrip()
        print 'general.connectivity() Out: ' + out
        print 'general.connectivity() Err: ' + err
        if(out == "0"):
            print 'general.connectivity() Successful'
            return True
        print 'general.connectivity() Failed'
        return False
    except Exception,e:
        print 'general.connectivity() Exception'
        return False

如果您想要端口扫描仪

import socket
from functools import partial
from multiprocessing import Pool
from multiprocessing.pool import ThreadPool
from errno import ECONNREFUSED

NUM_CORES = 4

def portscan(target,port):
    try:
        # Create Socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socketTimeout = 5
        s.settimeout(socketTimeout)
        s.connect((target,port))
        print('port_scanner.is_port_opened() ' + str(port) + " is opened")
        return port
    except socket.error as err:
        if err.errno == ECONNREFUSED:
            return False

# Wrapper function that calls portscanner
def scan_ports(server=None,port=None,portStart=None,portEnd=None,**kwargs):
    p = Pool(NUM_CORES)
    ping_host = partial(portscan, server)
    if portStart and portStart:
        return filter(bool, p.map(ping_host, range(portStart, portStart)))
    else:
        return filter(bool, p.map(ping_host, range(port, port+1)))

# Check if port is opened
def is_port_opened(server=None,port=None, **kwargs):
    print('port_scanner.is_port_opened() Checking port...')
    try:
        # Add More proccesses in case we look in a range
        pool = ThreadPool(processes=1)
                     try:
                        ports = list(scan_ports(server=server,port=int(port)))
                        print("port_scanner.is_port_opened() Port scanner done.")
                        if len(ports)!=0:
                            print('port_scanner.is_port_opened() ' + str(len(ports)) + " port(s) available.")
                            return True
                        else:
                            print('port_scanner.is_port_opened() port not opened: (' + port  +')')
                            return False
                    except Exception, e:
                        raise
                
    except Exception,e:
        print e
        raise
© www.soinside.com 2019 - 2024. All rights reserved.