IP Scanner

Code-Stücke können hier veröffentlicht werden.
Antworten
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Samstag 30. August 2014, 03:56

Ich habe hier mal ein Lan Scanner gebastelt :D
Was haltet ihr davon und wie "sauber" ist der Code? :)

Code: Alles auswählen


import socket


def is_up(addr):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(0.1)
    if not s.connect_ex((addr, 135)):
        s.close()
        return False
    else:
        return True

def main():
	liste = []
	for ip in range(1, 256):
		addr = "192.168.0." + str(ip)
		check = is_up(addr)
		if check == False:
			print(addr, "Belegt")
			liste.append(addr)
		elif check == True:
			print(addr, "Frei")
		else:
			print("Fehler")
	print()
	print("********************************")
	print()
	anzahl = len(liste)
	for ips in range(anzahl):
		print("Belegt : ", liste[ips])

if __name__ == "__main__":
	main()

Übrigends wurde dazwischen ein Switch geschaltet, ist halt für LAN-Feten gedacht. :)

mfg
Trayser
BlackJack

Samstag 30. August 2014, 05:02

@TrayserCassa: `is_up()` verwendet `connect_ex()` statt `connect()` kümmert sich aber nicht um eventuelle Ausnahmen die ja trotzdem noch auftreten können. `connect()` und eine entsprechende Ausnahmebehandlung wäre also einfacher.

Der Rückgabewert von `is_up()` ist falsch, denn wenn die Verbindung da ist, dann wird `False` zurückgegeben. Das macht keinen Sinn. Das die Zahl die zurückgegeben wird ”Falsch” bedeutet wenn die Verbindung zustande kommt, macht das ganze auch nicht wirklich gut lesbar wenn man einfach mit ``not`` arbeitet statt explizit mit ``== 0`` auf den ”guten” Fall zu testen. Bei `connect()` hätte man das Problem nicht.

`s` ist kein guter Name. Genau so wenig ist `liste` ein guter Name. `check` ist schon besser als Name an sich, aber eher für eine Funktion oder Methode, da er eine Tätigkeit beschreibt. Eigentlich wäre für diesen Wert `is_up` ein passender Name, wenn die Funktion nicht schon so heissen würde. Bei `ips` hätte ich keine ganzen Zahlen erwartet sondern zum Beispiel eine Liste mit IPs.

Die `main()`-Funktion ist nicht vier Leerzeichen pro Ebene eingerückt.

Das explizite Prüfen auf literale `True`- und `False`-Werte ist schlechter Stil. Bei dem Vergleich kommt doch nur wieder ein Wahrheitswert heraus, da hätte man auch gleich den nehmen können mit dem man das Literal vergleicht, beziehungsweise das gegebenfalls negieren.

Die drei Zweige für `True`, `False`, und anderes sind überflüssig weil die Funktion nur `True` oder `False` zurück gibt.

``for index in range(len(sequence)):`` ist ein „anti pattern”. Man kann stattdessen direkt über die Elemente der Liste iterieren.
Sirius3
User
Beiträge: 8301
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 30. August 2014, 09:57

zusätzlich: um Strings zusammen zu bauen, ist Stringformatierung einem »+ str(x)« vorzuziehen.
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Samstag 30. August 2014, 15:41

Danke für die Verbesserungsvorschläge :D

Ich hab versucht aus der Docu über "connect" schlauer zu werden, aber versteh die exceptions nicht genau wie ich die abfangen kann :K Daher habe ich noch "connect_ex" drin. Vielleicht mag mir da jemand weiterhelfen? :)

Die Namensgebung bei mir ist wirklich bescheiden :roll:
(Hier bin ich mit connection allerdings nicht zufrieden. Ihr?)

str() habe ich ausgetauscht :wink:

hier der Code:

Code: Alles auswählen

import socket


def check(addr):
	connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	connection.settimeout(0.1)
	if connection.connect_ex((addr, 135)) == 0:
		connection.close()
		return True
	else:
		return False

def main():
	check_liste = []
	for ip in range(1, 25):
		addr = "%s%d" % ("192.168.0.", ip)
		is_up = check(addr)
		if is_up == True:
			print(addr, "Belegt")
			check_liste.append(addr)
		elif is_up == False:
			print(addr, "Frei")
	print()
	print("********************************")
	print()
	for item in check_liste:
		print("Belegt : ", item)

if __name__ == "__main__":
	main()


Sirius3
User
Beiträge: 8301
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 30. August 2014, 16:08

@TrayserCassa: Du hast die expliziten Vergleiche auf »True« und »False« immer noch drin, wobei die “False”-Bedingung durch ein einfaches »else« ersetzt werden kann.

Gemeint war

Code: Alles auswählen

addr = "192.168.0.%d" % ip
BlackJack

Samstag 30. August 2014, 16:33

Ungetestet:

Code: Alles auswählen

import socket as socketlib
from contextlib import closing
from itertools import islice

from ipaddress import ip_network


def check_if_up(ip_address):
    socket = socketlib.socket(socketlib.AF_INET, socketlib.SOCK_STREAM)
    socket.settimeout(0.1)
    try:
        with closing(socket.connect((str(ip_address), 135))):
            return True
    except socketlib.error:
        return False


def main():
    used_ips = list()
    for address in islice(ip_network('192.168.0.0/27').hosts(), 25):
        if check_if_up(address):
            used_ips.append(address)
            print(address, 'ist belegt.')
        else:
            print(address, 'ist frei.')
    print()
    print('*' * 70)
    print()
    for address in used_ips:
        print('Belegt:', address)


if __name__ == '__main__':
    main()
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Montag 1. September 2014, 13:30

@BlackJack Da kommt ein Fehler falls es die IP gibt.

Code: Alles auswählen

192.168.0.1 ist frei.
192.168.0.2 ist frei.
192.168.0.3 ist frei.
192.168.0.4 ist frei.
192.168.0.5 ist frei.
192.168.0.6 ist frei.
192.168.0.7 ist frei.
192.168.0.8 ist frei.
192.168.0.9 ist frei.
192.168.0.10 ist frei.
192.168.0.11 ist frei.
192.168.0.12 ist frei.
192.168.0.13 ist frei.
192.168.0.14 ist frei.
192.168.0.15 ist frei.
192.168.0.16 ist frei.
192.168.0.17 ist frei.
192.168.0.18 ist frei.
192.168.0.19 ist frei.
Traceback (most recent call last):
  File "test2.py", line 34, in <module>
    main()
  File "test2.py", line 21, in main
    if check_if_up(address):
  File "test2.py", line 13, in check_if_up
    return True
  File "C:\Python34\lib\contextlib.py", line 152, in __exit_
    self.thing.close()
AttributeError: 'NoneType' object has no attribute 'close'
Habe zurzeit leider wenig Zeit deshalb vergebt mir, wenn ich mal ne Woche nicht da bin. ;)

mfg
Trayser
BlackJack

Montag 1. September 2014, 13:42

Ebenfalls ungetestet:

Code: Alles auswählen

def check_if_up(ip_address):
    socket = socketlib.socket(socketlib.AF_INET, socketlib.SOCK_STREAM)
    socket.settimeout(0.1)
    try:
        with closing(socket):
            socket.connect((str(ip_address), 135))
            return True
    except socketlib.error:
        return False
TrayserCassa
User
Beiträge: 97
Registriert: Donnerstag 2. Mai 2013, 19:11

Montag 1. September 2014, 18:17

Jap so Funktioniert es :)

Danke für die mühen BlackJack

mfg
Trayser
Antworten