在Python中ping服务器

在Python中,是否有一种方法可以通过ICMP来ping服务器,如果服务器响应则返回TRUE,如果没有响应则返回FALSE ?

746076 次浏览
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()

如果你不需要支持Windows,这里有一个非常简洁的方法:

import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)


#and then check the response...
if response == 0:
print hostname, 'is up!'
else:
print hostname, 'is down!'

这是因为如果连接失败,ping将返回一个非零值。(实际返回值因网络错误而异。)您还可以使用'-t'选项更改ping超时(以秒为单位)。注意,这将向控制台输出文本。

  1 #!/usr/bin/python
2
3 import os
4 import sys
5 import time
6
7 os.system("clear")
8 home_network = "172.16.23."
9 mine = []
10
11 for i in range(1, 256):
12         z =  home_network + str(i)
13         result = os.system("ping -c 1 "+ str(z))
14         os.system("clear")
15         if result == 0:
16                 mine.append(z)
17
18 for j in mine:
19         print "host ", j ," is up"

一个简单的我只是在一分钟内煮出来的..使用icmplib需要根privs下面的工作非常好! HTH < / p >

#!/usr/bin/python3


import subprocess as sp


ip = "192.168.122.60"
status,result = sp.getstatusoutput("ping -c1 -w2 " + ip)


if status == 0:
print("System " + ip + " is UP !")
else:
print("System " + ip + " is DOWN !")
#!/usr/bin/python3


import subprocess as sp


def ipcheck():
status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
if status == 0:
print("System " + str(pop) + " is UP !")
else:
print("System " + str(pop) + " is DOWN !")




pop = input("Enter the ip address: ")
ipcheck()

看起来很简单,但却让我头疼。我一直得到“icmp打开套接字操作不允许”,否则解决方案将挂起,如果服务器离线。然而,如果你想知道的是服务器是活的,并且你在该服务器上运行一个web服务器,那么curl将完成这项工作。如果您有ssh和证书,那么ssh和一个简单的命令就足够了。代码如下:

from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
ping="ssh %s date;exit"%(ip) # test ssh alive or
ping="curl -IL %s"%(ip)      # test if http alive
response=len(EasyProcess(ping).call(timeout=2).stdout)
return response #integer 0 if no response in 2 seconds

此脚本适用于Windows,也适用于其他操作系统: 它可以在Windows, Debian和macosx上工作,需要在solaris上测试

import os
import platform




def isUp(hostname):


giveFeedback = False


if platform.system() == "Windows":
response = os.system("ping "+hostname+" -n 1")
else:
response = os.system("ping -c 1 " + hostname)


isUpBool = False
if response == 0:
if giveFeedback:
print hostname, 'is up!'
isUpBool = True
else:
if giveFeedback:
print hostname, 'is down!'


return isUpBool


print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network

使用这个,它在python 2.7上测试过,工作很好,如果成功,它返回以毫秒为单位的ping时间,失败时返回False。

import platform,subproccess,re
def Ping(hostname,timeout):
if platform.system() == "Windows":
command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
else:
command="ping -i "+str(timeout)+" -c 1 " + hostname
proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
if matches:
return matches.group(1)
else:
return False

我有类似的要求,所以我实现它如下所示。它在Windows 64位和Linux上进行了测试。

import subprocess
def systemCommand(Command):
Output = ""
Error = ""
try:
Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
except subprocess.CalledProcessError as e:
#Invalid command raises this exception
Error =  e.output


if Output:
Stdout = Output.split("\n")
else:
Stdout = []
if Error:
Stderr = Error.split("\n")
else:
Stderr = []


return (Stdout,Stderr)


#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
print("Host [{}] is reachable.".format(Host))
else:
print("Host [{}] is unreachable.".format(Host))

当IP不可达时,subprocess.check_output()将引发异常。额外的验证可以通过从输出行“Packets: Sent = 2, Received = 2, Lost = 0 (0% loss)”中提取信息来完成。

< p > 此函数适用于任何操作系统(Unix、Linux、macOS和Windows) < br > Python 2和Python 3

< p >编辑:< br > 在@radato中,os.systemsubprocess.call取代。这避免了在您的主机名字符串可能无法验证的情况下存在壳注射漏洞
import platform    # For getting the operating system name
import subprocess  # For executing a shell command


def ping(host):
"""
Returns True if host (str) responds to a ping request.
Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
"""


# Option for the number of packets as a function of
param = '-n' if platform.system().lower()=='windows' else '-c'


# Building the command. Ex: "ping -c 1 google.com"
command = ['ping', param, '1', host]


return subprocess.call(command) == 0

注意,根据Windows上的@ikrase,如果你得到一个Destination Host Unreachable错误,这个函数仍然会返回True

解释

该命令在Windows和类unix系统中都是ping 选项-n (Windows)或-c (Unix)控制本例中设置为1的数据包数量

platform.system()返回平台名称在macOS上执行'Darwin'
subprocess.call()执行一个系统调用。subprocess.call(['ls','-l'])。< / p >

有一个名为pyp的模块可以做到这一点。可以用pip安装

pip install pyping

它使用起来非常简单,但是,当使用这个模块时,您需要root访问权限,因为它在底层制作原始数据包。

import pyping


r = pyping.ping('google.com')


if r.ret_code == 0:
print("Success")
else:
print("Failed with {}".format(r.ret_code))

确保pyping已安装或安装PIP安装PIP

#!/usr/bin/python
import pyping


response = pyping.ping('Your IP')


if response.ret_code == 0:
print("reachable")
else:
print("unreachable")

我在类似的情况下找到了这个问题。我尝试了pyping,但Naveen给出的例子在Python 2.7下的Windows中对我不起作用。

一个对我有用的例子是:

import pyping


response = pyping.send('Your IP')


if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")

因为我喜欢让我的Python程序在2.7和3版本上通用。在Linux, Mac OS和Windows平台上,我必须修改现有的示例。

# shebang does not work over all platforms
# ping.py  2016-02-25 Rudolf
# subprocess.call() is preferred to os.system()
# works under Python 2.7 and 3.4
# works under Linux, Mac OS, Windows


def ping(host):
"""
Returns True if host responds to a ping request
"""
import subprocess, platform


# Ping parameters as function of OS
ping_str = "-n 1" if  platform.system().lower()=="windows" else "-c 1"
args = "ping " + " " + ping_str + " " + host
need_sh = False if  platform.system().lower()=="windows" else True


# Ping
return subprocess.call(args, shell=need_sh) == 0


# test call
print(ping("192.168.17.142"))

我使用这篇文章中回答的想法,但只使用更新的推荐子进程模块和python3:

import subprocess
import platform


operating_sys = platform.system()
nas = '192.168.0.10'


def ping(ip):
# ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
shell_needed = True if operating_sys == 'Windows' else False


ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
success = ping_output.returncode
return True if success == 0 else False


out = ping(nas)
print(out)

在四处寻找之后,我最终编写了自己的ping模块,该模块旨在监视大量地址,是异步的,并且不使用大量系统资源。你可以在这里找到它:https://github.com/romana/multi-ping/它是Apache授权的,所以你可以在你的项目中以任何你认为合适的方式使用它。

实施我自己的方法的主要原因是其他方法的限制:

  • 这里提到的许多解决方案都需要将exec输出到命令行实用程序。如果您需要监控大量的IP地址,这是非常低效和资源消耗的。
  • 其他人提到了一些较老的python ping模块。我看了这些,最后,他们都有这样或那样的问题(比如没有正确设置数据包id),不能处理大量地址的ping-ing。

我的解决方法是:

def ping(self, host):
res = False


ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"


resultado = os.popen("ping " + ping_param + " " + host).read()


if "TTL=" in resultado:
res = True
return res

“TTL”是知道ping是否正确的方法。 Saludos < / p >

使用Multi-ping (pip install multiPing)我做了这个简单的代码(简单地复制和粘贴,如果你愿意!):

from multiping import MultiPing


def ping(host,n = 0):
if(n>0):
avg = 0
for i in range (n):
avg += ping(host)
avg = avg/n
# Create a MultiPing object to test hosts / addresses
mp = MultiPing([host])


# Send the pings to those addresses
mp.send()


# With a 1 second timout, wait for responses (may return sooner if all
# results are received).
responses, no_responses = mp.receive(1)




for addr, rtt in responses.items():
RTT = rtt




if no_responses:
# Sending pings once more, but just to those addresses that have not
# responded, yet.
mp.send()
responses, no_responses = mp.receive(1)
RTT = -1


return RTT

用法:

#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)

如果你想要一个单一的样本,第二个参数“10”可以忽略!

希望能有所帮助!

对于python3,有一个非常简单方便的python模块ping3:(pip install ping3,需要特权)。

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>> 0.215697261510079666

这个模块还允许自定义一些参数。

下面是一个使用Python的subprocess模块和底层操作系统提供的ping CLI工具的解决方案。在Windows和Linux上测试。支持设置网络超时。不需要根权限(至少在Windows和Linux上)。

import platform
import subprocess


def ping(host, network_timeout=3):
"""Send a ping packet to the specified host, using the system "ping" command."""
args = [
'ping'
]


platform_os = platform.system().lower()


if platform_os == 'windows':
args.extend(['-n', '1'])
args.extend(['-w', str(network_timeout * 1000)])
elif platform_os in ('linux', 'darwin'):
args.extend(['-c', '1'])
args.extend(['-W', str(network_timeout)])
else:
raise NotImplemented('Unsupported OS: {}'.format(platform_os))


args.append(host)


try:
if platform_os == 'windows':
output = subprocess.run(args, check=True, universal_newlines=True).stdout


if output and 'TTL' not in output:
return False
else:
subprocess.run(args, check=True)


return True
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
return False

编程ICMP ping很复杂,因为发送原始ICMP包需要更高的权限,并且调用ping二进制是丑陋的。对于服务器监控,您可以使用名为TCP平的技术来实现相同的结果:

# pip3 install tcping
>>> from tcping import Ping
# Ping(host, port, timeout)
>>> ping = Ping('212.69.63.54', 22, 60)
>>> ping.ping(3)
Connected to 212.69.63.54[:22]: seq=1 time=23.71 ms
Connected to 212.69.63.54[:22]: seq=2 time=24.38 ms
Connected to 212.69.63.54[:22]: seq=3 time=24.00 ms

在内部,这只是建立一个到目标服务器的TCP连接,并立即丢弃它,测量所消耗的时间。这个特殊的实现有点局限,因为它不能处理封闭的端口,但对于您自己的服务器来说,它工作得很好。

很多答案都忽略的一点是(至少在Windows中)ping命令如果接收到“目标主机不可达”的应答,则返回0(表示成功)。

下面是我的代码,它检查b'TTL='是否在响应中,因为它只在ping到达主机时才出现。注意:此代码的大部分是基于这里的其他答案。

import platform
import subprocess


def ping(ipAddr, timeout=100):
'''
Send a ping packet to the specified host, using the system ping command.
Accepts ipAddr as string for the ping destination.
Accepts timeout in ms for the ping timeout.
Returns True if ping succeeds otherwise Returns False.
Ping succeeds if it returns 0 and the output includes b'TTL='
'''
if platform.system().lower() == 'windows':
numFlag = '-n'
else:
numFlag = '-c'
completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
stdout=subprocess.PIPE,    # Capture standard out
stderr=subprocess.STDOUT)  # Capture standard error
# print(completedPing.stdout)
return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)


print(ping('google.com'))

注意:这捕获输出而不是打印输出,所以如果你想看到ping的输出,你需要在返回之前打印completedPing.stdout

WINDOWS ONLY -不敢相信没有人破解了Win32_PingStatus 使用一个简单的WMI查询,我们免费返回一个包含非常详细信息的对象

import wmi




# new WMI object
c = wmi.WMI()


# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')


# how big is this thing? - 1 element
print 'length x: ' ,len(x)




#lets look at the object 'WMI Object:\n'
print x




#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
print i






#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
print 'Response:\t', i.ResponseTime, 'ms'
print 'TTL:\t', i.TimeToLive




#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'

样本输出

我借鉴了其他答案。尝试简化和最小化查询。

import platform, os


def ping(host):
result = os.popen(' '.join(("ping", ping.param, host))).read()
return 'ttl=' in result.lower()


ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"

编辑:根据奥利维尔B的评论,忽略返回的大小写。

我的版本的ping函数:

  • 适用于Python 3.5及更高版本,适用于Windows和Linux。
  • 在Windows上,如果ping命令失败并且“目标主机不可达”,则返回False。
  • 并且不显示任何输出,无论是弹出窗口还是命令行。
import platform, subprocess


def ping(host_or_ip, packets=1, timeout=1000):
''' Calls system "ping" command, returns True if ping succeeds.
Required parameter: host_or_ip (str, address of host to ping)
Optional parameters: packets (int, number of retries), timeout (int, ms to wait for response)
Does not show any output, either as popup window or in command line.
Python 3.5+, Windows and Linux compatible
'''
# The ping command is the same for Windows and Linux, except for the "number of packets" flag.
if platform.system().lower() == 'windows':
command = ['ping', '-n', str(packets), '-w', str(timeout), host_or_ip]
# run parameters: capture output, discard error messages, do not show window
result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, creationflags=0x08000000)
# 0x0800000 is a windows-only Popen flag to specify that a new process will not create a window.
# On Python 3.7+, you can use a subprocess constant:
#   result = subprocess.run(command, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)
# On windows 7+, ping returns 0 (ok) when host is not reachable; to be sure host is responding,
# we search the text "TTL=" on the command output. If it's there, the ping really had a response.
return result.returncode == 0 and b'TTL=' in result.stdout
else:
command = ['ping', '-c', str(packets), '-w', str(timeout), host_or_ip]
# run parameters: discard output and error messages
result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
return result.returncode == 0

你想怎么用就怎么用。

我需要一个更快的ping扫描,我不想使用任何外部库,所以我决定使用内置asyncio使用并发。

此代码需要python 3.7 +,并且只在Linux上制作和测试。它不能在Windows上工作,但我相信你可以很容易地将其更改为在Windows上工作。

我不是asyncio的专家,但我使用了这篇伟大的文章使用并发性加速Python程序,我想出了这些代码行。我试图使它尽可能简单,所以很可能您需要添加更多的代码来满足您的需求。

它不会返回true或false,我认为让它打印响应ping请求的IP会更方便。我认为这是相当快的,ping 255 ips在近10秒。

#!/usr/bin/python3


import asyncio


async def ping(host):
"""
Prints the hosts that respond to ping request
"""
ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
await ping_process.wait()


if ping_process.returncode == 0:
print(host)
return




async def ping_all():
tasks = []


for i in range(1,255):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)


await asyncio.gather(*tasks, return_exceptions = True)


asyncio.run(ping_all())

样例输出:

192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6

请注意,IP不是按顺序排列的,因为IP在它响应时就会打印出来,所以先响应的就会先打印出来。

使用python3中的套接字包:

import socket


def ping_server(server: str, port: int, timeout=3):
"""ping server"""
try:
socket.setdefaulttimeout(timeout)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server, port))
except OSError as error:
return False
else:
s.close()
return True

在windows或linux中Ping它们,返回一个排序的列表。这是@Ahmed Essam和@Arno回复的混合/修正。

import asyncio
import re


import platform
isWindows = platform.system()




async def ping(host):
cmd = 'ping {} {} 1'.format(host, '-n' if isWindows else '-c')
ping_proc = \
await asyncio.create_subprocess_shell(cmd, stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
stdout, stderr = await ping_proc.communicate()
outstr = stdout.decode()


if ping_proc.returncode == 0:
delay = int(re.search(r'(?:time=)([\d]*)', outstr).group(1)) if 'time=' in outstr else -1
if delay >= 0:
# print('{} {}ms'.format(host, delay))
return [host, delay]


return [host, None]




async def ping_all():
tasks = []


for i in range(1, 256):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)


retList = await asyncio.gather(*tasks, return_exceptions=True)
retList = [x for x in retList if x[1] is not None]
retList.sort(key=lambda x: int(x[0].split('.')[-1]))


return retList




loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
pingRet = loop.run_until_complete(ping_all())


for ip, d in pingRet:
print('{:<16s} {}ms'.format(ip, d))

在linux上,可以创建ICMP数据报(不是原始)套接字,而不需要root(或setuid或CAP_NET_RAW): https://unix.stackexchange.com/a/592914。最后我得到了

$ id
uid=1000(raylu) gid=1000(raylu) [...]
$ sudo sysctl net.ipv4.ping_group_range='1000 1000'
import socket
import struct
import time


def main():
ping('192.168.1.10')


def ping(destination):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.getprotobyname('icmp'))
sock.settimeout(10.0)
start_time = time.time_ns() # python 3.7+ only


payload = struct.pack('L', start_time)
sock.sendto(encode(payload), (destination, 0))
while (time.time_ns() - start_time) // 1_000_000_000 < 10:
try:
data, source = sock.recvfrom(256)
except socket.timeout:
print('timed out')
return
message_type, message_code, check, identifier, sequence_number = struct.unpack('bbHHh', data[:8])
if source == (destination, 0) and message_type == ICMP.ECHO_REPLY and data[8:] == payload:
print((time.time_ns() - start_time) // 1_000_000, 'ms')
break
else:
print('got unexpected packet from %s:' % source[0], message_type, data[8:])
else:
print('timed out')


def encode(payload: bytes):
# calculate checksum with check set to 0
checksum = calc_checksum(icmp_header(ICMP.ECHO_REQUEST, 0, 0, 1, 1) + payload)
# craft the packet again with the checksum set
return icmp_header(ICMP.ECHO_REQUEST, 0, checksum, 1, 1) + payload


def icmp_header(message_type, message_code, check, identifier, sequence_number) -> bytes:
return struct.pack('bbHHh', message_type, message_code, check, identifier, sequence_number)


def calc_checksum(data: bytes) -> int:
'''RFC 1071'''
# code stolen from https://github.com/alessandromaggio/pythonping/blob/a59ce65a/pythonping/icmp.py#L8
'''
MIT License


Copyright (c) 2018 Alessandro Maggio


Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:


The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.


THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
'''
subtotal = 0
for i in range(0, len(data)-1, 2):
subtotal += (data[i] << 8) + data[i+1]
if len(data) % 2:
subtotal += (data[len(data)-1] << 8)
while subtotal >> 16:
subtotal = (subtotal & 0xFFFF) + (subtotal >> 16)
check = ~subtotal
return ((check << 8) & 0xFF00) | ((check >> 8) & 0x00FF)


class ICMP:
ECHO_REPLY = 0
ECHO_REQUEST = 8

虽然这里其他答案建议的许多软件包也可以工作

我自己的方法结合了上面的几个答案:


def ping(host, show_log=False, package_count=1):
ping.param = "-n" if platform.system().lower() == 'windows' else "-c"
result = subprocess.run(['ping', ping.param, str(package_count), host],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output = result.stdout
if show_log:
print('return code: ', result.returncode)
print(output.decode("utf-8"))
return result.returncode == 0 and (b'TTL=' in output or b'ttl=' in output)

在OSX Monterey上测试。

import os #to get clear screen
import subprocess as sp #to get system ping
os.system("clear") #clear screen
print('Wait or Press Ctrl+Z to Terminate\n') #notice to terminate or wait
for i in range(255): #0 to 255 loop
ip='192.168.1.'+str(i) #concatenating str and int
s,r=sp.getstatusoutput("ping -c1 -w2 " + ip) #ping and store status in s
if s==0: #if status is 0 equal to pass
print(ip+" is UP ✓ ") #output
else: #if status is not 0 equal to fail
pass #skip and try next ip from loop

如果您的服务器不支持ICMP(防火墙可能会阻止它),它很可能仍然在TCP端口上提供服务。在这种情况下,你可以像这样执行TCP平1(平台独立,无需安装额外的python模块):

import socket


def isReachable(ipOrName, port, timeout=2):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(timeout)
try:
s.connect((ipOrName, int(port)))
s.shutdown(socket.SHUT_RDWR)
return True
except:
return False
finally:
s.close()

该代码取自在这里,并仅对其进行了轻微修改。


1 A TCP平实际上并不存在,因为在ISO/OSI第3层上使用ICMP执行ping。TCP ping在ISO/OSI第4层执行。它只是试图以最基本的方式连接到TCP端口,即不传输任何数据,而是在连接后立即关闭连接。