這是ZeroMQ UDP ping功能,它適用於UDP discovery, model 1 in Python,它禁用廣播,ping一個IP地址,在第一個回覆後返回,添加一個計數器來限制ping嘗試次數,並在消息接收期間增加額外的錯誤處理。後者是因爲我的網絡中的一個主機強行關閉了導致socket.error的連接:[Errno 10054]。它已經過測試,發現可以與Python 2.7.10和3.4.3一起使用。
from __future__ import print_function
import os
import socket
import sys
import time
import zmq
def udpping(ip):
PING_PORT_NUMBER = 9999
PING_MSG_SIZE = 1
PING_INTERVAL = 1 # once per second, sets minimum initial timeout
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# uncomment the line below for broadcast to 255.255.255.255
# sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.bind(('', PING_PORT_NUMBER))
poller = zmq.Poller()
poller.register(sock, zmq.POLLIN)
ping_at = time.time()
limit = 5 # only limit ping attempts will be made
count = 0
while True:
count += 1
timeout = ping_at - time.time()
if timeout < 0:
timeout = 0
try:
events = dict(poller.poll(1000* timeout))
except KeyboardInterrupt:
return (1,None,None)
try:
if sock.fileno() in events:
msg, addrinfo = sock.recvfrom(PING_MSG_SIZE)
return (2,"found %s:%d" % addrinfo,None)
except socket.error as e:
return (3,'error during msg receive:',e)
if time.time() >= ping_at:
# the line below is for broadcasting
# sock.sendto(b'!', 0, ("255.255.255.255", PING_PORT_NUMBER))
sock.sendto(b'!', 0, (ip, PING_PORT_NUMBER))
ping_at = time.time() + PING_INTERVAL
if count == limit:
return (4,limit,None)
ip = '192.168.159.21'
c,m,e = udpping(ip)
下面顯示了輸出處理。對於二進制決策,只有在c == 2的情況下ping才能成功。
if c == 1:
print('ping attempt stopped by KeyboardInterrupt')
elif c == 2:
print(m)
elif c == 3:
print(m,e)
elif c == 4:
print('no response from',ip,'after',m,'attempts')
# prints 'found 192.168.159.21:9999' immediately in my net
可能會設置短暫超時?那麼結果會更快 –
@勞倫斯·本森和確切的命令是什麼? – Ali
也許不是檢查虛擬機,而是讓虛擬機發送一些關於它的存在的確認。就像是從虛擬機發送到運行服務器實例的其他機器的SYN數據包,可能會接受連接,記錄它們並丟棄它們。 http://www.secdev.org/projects/scapy/doc/usage.html#tcp-port-scanning –