Port Check

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
fichtknick
User
Beiträge: 8
Registriert: Mittwoch 20. März 2013, 22:21

Halli Hallo

Ich wollte hier mal mein ganz alleine geschriebenes programm zeigen und vor allem kritik einfangen, da ich noch unerfahren bin in sachen netzwerkprogrammierung.
Es ist ein programm das checkt auf welchen ports es sich verbinden kann, sprich also welche offen sind. Das hoffeich jedenfalls ;) Wie gesagt, man findet wenig im Netz über python und netzwerkprogrammierung und was Englishes angeht, so verstehe ich es zwar eig. recht gut, nur die fachbegriffe liegen mir nicht so. :)

Daher, schaut es Euch mal bitte an und zeigt mir wo ich falsch liege und/oder wie man das viel effizienter machen könnte, ich bin auch so selbst kritisch, das ich sicherlich weiss dass das nicht das gelbe vom Ei ist. ;) ABER: Es funktioniert auf jedenfall, so viel wie ich getestet habe und auch gesehen, aber ich min mir nicht sicher ob es wirklich ganz genau so funktioniert wie ich mir das vorstelle. ;)

ich habe es bei nur im script ordner ohne .py gespeichert und nenne es porch, also muss man es: porch ip_or_url start_port end_port, starten, somit kann man einen bestimmten port bereich testen und muss nicht unbedingt von 1 bis 65535 z.b. ;)

Code: Alles auswählen

#!/usr/bin/env python3
# -*- Coding: utf-8 -*-

#################################
#                               #
#        Port Check v0.2        #
#    fichtknick@lavabit.com     #
#################################

import socket
from sys import exit, argv

def make_socket():
	# Build a Socket
    try:
        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except:
        print("\nSocket build fail\n")
        exit()
        
    return soc

def test(host, start_port, end_port):
    # Let's test it
    port_counter = start_port
    while port_counter <= end_port:
        soc = make_socket()
	
        try:
            soc.connect((host, port_counter))
            print("\n--> On Port: {} Connected.".format(port_counter))
            soc.close()
        except:
            pass
            
        port_counter += 1

def how_to():
    # Fals nicht oder zuviele Parameter gegeben wurden
    print("\nNeed parameter's, Example: ")
    print("\nporch ip_or_url start_port end_port\n")

def main():
	
    print("\nPortcheck v0.2\n")
    
    if len(argv) < 4 or len(argv) > 4:
        how_to()
    else:
        # ip or url, can be write...
        try:
            host = socket.gethostbyname(argv[1])
        except socket.gaierror:
            print("Connection Fail: Host down ? ")
            exit()
        start_port = int(argv[2])
        end_port   = int(argv[3])
        
        test(host, start_port, end_port)
  
        print("\nTest Done...\n")
        
if __name__=='__main__':
	main()
Grüsse Euch und erschlagt mich nicht gleich mit kritik und entdeckten fehlern ;)
BlackJack

@fichtknick: Es wird Benutzerinteraktion mit Programmlogik vermischt. Und `sys.exit()` sollte man nicht in ”tief” verschachtelten Funktionsaufrufen verwenden. Das Programm einfach so abzubrechen ist etwas was Code sehr schlecht wiederverwendbar macht wenn es Funktionen gibt, die das Programm ohne Eingriffsmöglichkeit beenden können. Ich würde mit `sys.exit()` sparsam umgehen und versuchen den Quelltext ohne diese Funktion zu strukturieren. Andererseits ist das ein Weg um dem Aufrufer des Programms eine Information zurück zu geben und per Konvention geben Programme etwas ungleich 0 zurück, wenn es Fehler oder Probleme gab.

Die Fehlerbehandlung ist generell nicht gut. Es wäre ja zum Beispiel interessant zu wissen *warum* ein Socket nicht erstellt werden konnte. Das kann zum Beispiel auch passieren wenn ein Tippfehler in dem ``try``-Block ist und deshalb ein `NameError` oder ein `AttributeError` ausgelöst wird. Genau so sollte man in der `test`-Funktion nicht einfach *alle* Ausnahmen ignorieren, sondern gezielt nur die, die man dort auch tatsächlich erwartet.

In der `test()`-Funktion würde sich statt der ``while``-Schleife eine ``for``-Schleife mit `range()` anbieten.

Der Test auf Anzahl der Argumente lässt sich einfacher Ausdrücken. Länge kleiner vier oder Länge grösser vier ist Länge ungleich vier: ``if len(argv) != 4:``.

Argumente und Hilfetextausgabe lassen sich mit dem `argparse`-Modul aus der Standardbibliothek verarbeiten.

Allgemein zur Socketprogrammierung kann man übrigens auch Texte für C und andere Sprachen heran ziehen, welche die BSD-Socket-API verwenden, denn das `socket`-Modul ist nur eine dünne Schicht über diese Standard-API.
fichtknick
User
Beiträge: 8
Registriert: Mittwoch 20. März 2013, 22:21

wow vielen dank, dann werde ich mich jetzt gleich nochmals dran setzten :)

Hat mir schon wunderbar geholfen, ich werde jetzt nochmals drüber gehen mit deinem Text nebenan.

Danke und Happy Greetings :)
fichtknick
User
Beiträge: 8
Registriert: Mittwoch 20. März 2013, 22:21

so, ein paar sachen, aber noch nicht alles wurde verbessert ;) bin eben auch noch am durchlesen, was es in sachen socket, alles für errors geben kann. Dennoch habe ich ein problem, was mich gerade echt schafft, das programm funktioniert nicht mehr, also nicht mehr so ganz... bis jetzt sieht das ganze so aus:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- Coding: utf-8 -*-

#################################
#                               #
#        Port Check v0.2        #
#    fichtknick@lavabit.com     #
#################################

import socket
from sys import argv

def make_socket():
	# Build a Socket
    try:
		# at the moment only TCP
        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    except socket.error:
        print("\nSocket build fail")
        
    return soc

def test(host, start_port, end_port):
    # Let's test it
    for port_counter in range(start_port, end_port):
        soc = make_socket()
	
        try:
            soc.connect((host, port_counter))
            print("\n--> On Port: {} Connected.".format(port_counter))
            soc.close()
        except:
            pass

def how_to():
    # Fals nicht oder zuviele Parameter gegeben wurden
    print("\nNeed parameter's, Example: ")
    print("\nporch <ip_or_url> <start_port> <end_port>\n")

def main():
	
    print("\nPorch v0.2\..n")
    
    if len(argv) != 4:
        how_to()
    else:
        # ip or url, can be write...
        try:
            host = socket.gethostbyname(str(argv[1]))
        except socket.gaierror:
            print("Connection Fail: Host down ? ")
            exit()
        start_port = int(argv[2])
        end_port   = int(argv[3])
        
        test(host, start_port, end_port)
  
        print("\nTest Done...\n")
        
if __name__=='__main__':
	main()
Im LAN funktioniert es einwandfrei, ich habe 2 Pc's einen laptop und ein webserver, und es funktioniert zu jedem und von jedem rechner an die anderen und auch "porch localhost 0 60000" funktioniert super, nur wen ich z.b. "porch www.irgendwas.irgendwas 70 82" eingebe geht nix egal auf welche seite/ip egal von welchem port bis zu port, sobald es ins internet geht muss ich immer "ctrl c" drücken damit die for schleife einmal iteriert... also im lan funktioniert es super, im/zum internet nicht oder ich iretiere die for schleife manuel mit ctrl c ;) kann mir da jemand, des rätsels lösung sagen erläutern ? grüsse
BlackJack

@fichtknick: Irgendein Aufruf scheint zu blockieren.

Du hast übrigens einen Fehler in `make_socket()`: Wenn eine Ausnahme auftritt wird 'Socket build fail' ausgegeben und dann wird versucht beim ``return`` etwas zurück zu geben was überhaupt nicht definiert wurde. Die Ausnahmebehandlung ist IMHO in der Funktion sowieso am falschen Platz.
fichtknick
User
Beiträge: 8
Registriert: Mittwoch 20. März 2013, 22:21

top, stimmt mit dem return... ist mir erst jetzt aufgefallen wo du es sagst.. :)

hab jetzt die funktion make_socket wie folgt geändert:

Code: Alles auswählen

def make_socket():
    # Build a Socket
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.settimeout(1)
    return soc
und es funktioniert alles wieder so, wie es sollte. :)
Antworten