Возникла тут тривиальная задача посмотреть какие IP заняты в локальной сети. И конечно есть целая куча всяких программ сканеров, но хочется же что то свое сварганить )
Немного подумав, пришел к выводу что самое простое это просто пингануть всю локальную сеть. На самом деле Ping это название утилиты которая входит в ОС, а сама эта хрень называется ICMP Echo-Request( запрос ) и ICMP Echo-Reply( ответ ). К стати пинг не гарантирует что устройство не доступно, так как ответ на пинг может быть просто запрещен на устройстве или брандмауэре .
ICMP (Internet Control Message Protocol — протокол межсетевых управляющих сообщений) — сетевой протокол, входящий в стек протоколов TCP/IP.
Вообщем он там зарыт где то глубоко глубоко, писать реализацию своего стека мне уж точно не под силу. По этому будем пользоваться уже готовой системной утилитой. Для отправки ICMP Echo-Request мы должны иметь права АДМИНИСТРАТОРА ( root ). Поехали.
Первым дело узнаем IP нашего сетевого интерфейса, в какой мы вообще сети :
import socket
def getMyIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Создаем сокет (UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Настраиваем сокет на BROADCAST вещание.
s.connect(('<broadcast>', 0))
return s.getsockname()[0]
- socket.AF_INET — для сокета используем IPv4 .
- socket.SOCK_DGRAM — тип сокета. Датаграммный сокет (UDP) .
- getsockname() — Вернет сокету его собственный адрес.
Это наверное не самый элегантный способ.Но должен работать в любой локальной сети, которая позволяет широковещательную рассылку UDP и не требует доступа куда либо. Есть еще идее ? Пишите в комментах )
Далее нам надо узнать платформу. В Windows и Linux команда будет выглядеть немного по разному. Для определение ОС в Питоне есть команды platform.system() которая входит в стандартную библиотеку OS . Возвращает имя системы / ОС, например 'Linux'
,'Windows'
, или 'Java'
. Пустая строка возвращается, если значение не может быть определено :
import os
import platform
oc = platform.system()
if (oc == "Windows"):
ping_com = "ping -n 1 "
else:
ping_com = "ping -c 1 "
Введем диапазон адресов для сканирования :
start_point = int(input("Enter the Starting Number: "))
end_point = int(input("Enter the Last Number: "))
Ну теперь напишем саму функцию сканирования :
net = getMyIp()
net_split = net.split('.')
a = '.'
net = net_split[0] + a + net_split[1] + a + net_split[2]+ a
def scan_ip(ip):
addr = net + str(ip)
comm = ping_com + addr
response = os.popen(comm)
data = response.readlines()
for line in data:
if 'TTL' in line:
print(addr, "--> Ping Ok")
break
- os.popen(comm) — Класс Popen Python выполняет дочернюю программу в новом процессе.
- data = response.readlines() — читаем ответ от утилиты.
- Дальше просто парсим ответ, если есть TTL в строке значит пинг успешен.
Еще добавим многопоточность что бы быстрей пинговать. Весь код целиком :
import os
import platform
import threading
import socket
from datetime import datetime
def getMyIp():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #Создаем сокет (UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Настраиваем сокет на BROADCAST вещание.
s.connect(('<broadcast>', 0))
return s.getsockname()[0]
def scan_Ip(ip):
addr = net + str(ip)
comm = ping_com + addr
response = os.popen(comm)
data = response.readlines()
for line in data:
if 'TTL' in line:
print(addr, "--> Ping Ok")
break
net = getMyIp()
print('You IP :',net)
net_split = net.split('.')
a = '.'
net = net_split[0] + a + net_split[1] + a + net_split[2] + a
start_point = int(input("Enter the Starting Number: "))
end_point = int(input("Enter the Last Number: "))
oc = platform.system()
if (oc == "Windows"):
ping_com = "ping -n 1 "
else:
ping_com = "ping -c 1 "
t1 = datetime.now()
print("Scanning in Progress:")
for ip in range(start_point, end_point):
if ip == int(net_split[3]):
continue
potoc = threading.Thread(target=scan_Ip, args=[ip])
potoc.start()
potoc.join()
t2 = datetime.now()
total = t2 - t1
print("Scanning completed in: ", total)

Получилось достаточно простая программка. В следующий раз добавим еще отображение MAC адреса и Vendor . Можно еще добавить определение сетевого имени ПК и т.д.
А вы сами проверяли написанный код программы?
Ошибка в названии переменной oc.
А вы проверяли код программы ?
Только что просто скопировал и запустил программу :
You IP : 192.168.0.107
Enter the Starting Number: 0
Enter the Last Number: 254
Scanning in Progress:
192.168.0.1 —> Ping Ok
Scanning completed in: 0:00:13.125223
Process finished with exit code 0
Ни каких проблем нету. Ну или выражайтесь яснее , что у вас там не правильно ))))
Спасибо за быстрый ответ.
Да, проверял. Если код скопировать полностью, в переменной «ос» — мой редактор кода (PyCharm) находит кириллический символ.
Да , действительно у меня тоже подсвечивает что не ASCII символ. Но самое забавное что запускает. Спасибо за найденную ошибку.