为了工作中碰到的一些问题,也是为了好玩,做了一个在局域网中搜索设备(代码中可设定搜索IP的范围),并且获取设备的IP以及MAC地址。用以发送关机和网络唤醒的命令。
实现关机和网络唤醒的前提是:
1、目标主机关闭了防火墙。
2、网卡设置了允许网络唤醒,并且主板BIOS中也没有相应的设置限制
3、我是通过 ping IP地址,然后查看 arp缓存中的MAC实现的
具体步骤上代码
#coding:GB2312
import socket
import struct
import os
import re
import time
from tkinter import *
root = Tk()
def outputCmd(cmd):
r = os.popen(cmd)
text = r.read()
r.close()
return text
def checkMAC(ipaddress):
arp_cmd = "arp -a"
arp_result = outputCmd(arp_cmd)
# print(arp_result)
# ip2 = "(?<=\.2 ).+(?= +?)"
# ip2 = "\.10 [ ]+([\w-]+)"
ip2 =ipaddress+" [ ]+([\w-]+)"
ip2MAC = re.findall(ip2, arp_result)
if ip2MAC == []:
return 0
else:
# print(" %s 的MAC是:%s" % (ipaddress, ip2MAC[0]))
print(" 检测到MAC为:%s" % (ip2MAC[0]))
return ip2MAC[0]
def checkDevice_and_writeInTxt():
val = 0
netport = 0
print("稍等片刻,局域网设备搜索中......")
print("************************************")
f = open("IP_MAC.txt", "w+")
for val in range(13, 18):
dest_ip = "192.168.0." + val.__str__()
cmd_pingAll = "ping " + dest_ip + " -n 2 "
result = outputCmd(cmd_pingAll)
find_TTL = result.find("TTL")
if find_TTL != -1:
netport += 1
print("存在IP为%s 的设备" % dest_ip, end=' ')
result = checkMAC(dest_ip)
if result == 0:
print(" 本机IP为: %s MAC不会告诉你的啦......" % dest_ip)
else:
f.write(dest_ip+' >>> '"%s\n" %result) #写入 ip MAC 到文件中
print("************************************")
print("共有 %s 个设备" % netport)
#f.write("***By LHT %s***"%time.asctime(time.localtime(time.time())))
f.close()
"""发送魔包唤醒macaddress 的设备"""
def wake_on_lan(macaddress):
""" Switches on remote computers using WOL. """
# Check macaddress format and try to compensate.
if len(macaddress) == 12:
pass
elif len(macaddress) == 12 + 5:
sep = macaddress[2]
macaddress = macaddress.replace(sep, '')
# print(macaddress)
else:
raise ValueError('Incorrect MAC address format')
# Pad the synchronization stream.
data = ''.join(['FFFFFFFFFFFF', macaddress * 20])
send_data = b''
# Split up the hex values and pack.
for i in range(0, len(data), 2):
send_data = b''.join([send_data, struct.pack('B', int(data[i: i + 2], 16))])
# print(send_data)
# Broadcast it to the LAN.
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(send_data, ('<broadcast>', 7))
time.sleep(1)
sock.sendto(send_data, ('<broadcast>', 7))
time.sleep(1)
sock.sendto(send_data, ('<broadcast>', 7))
"""关机命令"""
def power_off(IP_dest):
print(IP_dest)
os.system("net use ""\\\\" + IP_dest[0] + " \"admin\"/user:\"admin\"")
poweroff_cmd = "shutdown -s -m " + "\\\\" + IP_dest[0] + " -t 0"
# print(poweroff_cmd)
os.system(poweroff_cmd)
"""读取txt中记录的 IP的MAC地址 执行开机"""
def readTxtMac_and_wakeOnLan():
f = open("IP_MAC.txt", "r")
fa = f.readlines()
for a in range(0, len(fa)):
fb = fa[a]
findword = "[>>>]. ([\w-]+)"
MAC_dest = re.findall(findword, fb)
print("进行唤醒MAC为%s 的设备中。。。" %MAC_dest)
wake_on_lan(MAC_dest[0])
"""读取txt中记录的 IP地址 执行关机"""
def readTxtMac_and_powerOff():
f = open("IP_MAC.txt", "r")
fa = f.readlines()
for a in range(0, len(fa)):
fb = fa[a]
findword = "([\.\d]+) "
IP_dest = re.findall(findword, fb)
# print(IP_dest)
print("进行关闭IP为%s 的设备中。。。" % IP_dest)
power_off(IP_dest)
if __name__ == '__main__':
def g():
if b['text'] == '开机':
b['text'] = '关机'
readTxtMac_and_wakeOnLan()
# print('开始')
else:
b['text'] = '开机'
checkDevice_and_writeInTxt()
readTxtMac_and_powerOff()
# print('结束')
b = Button(root, text='关机', font=('KaiTi', 36, 'bold'), bg='pink', fg='green', bd=2, width=10, command=g)
b.pack()
root.mainloop()