检查远程主机是否在Python中运行

时间:2010-03-28 23:40:56

标签: python network-programming network-protocols

如何在没有端口号的情况下检查远程主机是否已启动?有没有其他方法我可以检查其他方式然后使用常规ping。

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

7 个答案:

答案 0 :(得分:9)

这对我来说很好:

HOST_UP  = True if os.system("ping -c 1 " + SOMEHOST) is 0 else False

答案 1 :(得分:1)

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

答案 2 :(得分:0)

你能做的最好的事情是:

  • 尝试连接已知端口(例如,端口80或443用于HTTP或HTTPS);或
  • Ping网站。请参阅Ping a site in Python?

许多网站会阻止ICMP(用于ping网站的协议),因此您必须事先知道相关主机是否已启用它。

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

这完全取决于你需要知道什么。

答案 3 :(得分:0)

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

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

为什么你需要知道主持人是否“正常”,也许还有更好的方法。

答案 4 :(得分:0)

如何尝试需要像“任务列表”这样的RPC的东西呢?命令与ping一起使用?

答案 5 :(得分:0)

我会使用端口扫描程序。原始问题表明您不想使用端口。然后,您需要指定要监视的协议(是,这需要一个端口)(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     
        else:
            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

答案 6 :(得分:0)

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

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

-c 5 

如果所有请求均通过,则增加ping请求的数量

PS。仅在Linux上有效,在Windows上始终返回True