[Errno 9] Bad file descriptor

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Minzent
User
Beiträge: 16
Registriert: Dienstag 11. September 2018, 15:09

Sehr geehrte Damen und Herren,

In meinem Skript, das ein Socket aufbaut, auf eine Nachricht eines anderen Pi´s wartet um daraufhin dann etwa ein Relais zu schließen, bekomme ich zum Schluss immer die Fehlermeldung

[Errno 9] Bad file descriptor

was darauf zurückzuführen ist, dass das Programm aus einem anderen geschlossen bzw. nicht von selbst beendet. Nun bin ich noch nicht sehr fit in Python und tue mich schwer den Fehler zu beheben... Um die Findung einfacher zu machen zeige ich nur die Teile des SKripts, von denen ich glaube, dass sie zu dem Fehler führen.

Für eure Hilfe wäre ich sehr dankbar :oops:

Code: Alles auswählen

def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created.")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    print("Socket bind complete.")
    return s

def setupConnection(server):
    server.listen(1) # Allows one connection at a time.
    conn, address = server.accept()
    print("Connected to: " + address[0] + ":" + str(address[1]))
    return conn


def dataTransfer(conn, s):
    while True:
        data = conn.recv(1024) # receive the data
        data = data.decode('utf-8')
        dataMessage = data.split(' ', 1)
        command = dataMessage[0]
        if command == 'close_charge':
            close_relais_charge()
            print("Relais geschlossen")
            s.close()
            conn.close()
 
  def stop_charge(bus):
    close_relais_charge()
    send_message(bus, STOP_CHARGE)
    print("Charging stopped. Battery full. Stop program")
            
 def main():

    try:
        s = setupServer() #Socket herstellen und daten empfangen
        while True:
            try:
                conn = setupConnection(s)
                dataTransfer(conn, s)
            except Exception as ex:
                print (ex)
                break
    except KeyboardInterrupt:
        print(Fore.RED + '\n\r keyboard interrupted\n')
        print(Fore.RESET)
    finally:
        stop_charge(bus)
Hier noch die printausgabe:

Socket created.
Socket bind complete.
Connected to: 192.168.1.161:38814
Relais geschlossen
[Errno 9] Bad file descriptor
Charging stopped. Battery full. Stop program


nach "Socket bin complete" wartet das Programm auf den Befehl des anderen Pi´s. Kommt dieser, geht es weiter mit dem Rest (connected to etc...)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

allgemein: die Einrückungen sind kaputt. Funktionsnamen schreibt man nach Konventio klein_mit_unterstrich, Abkürzungen (conn) oder Einbuchstabige Variablennamen (s) vermeiden.

setupServer: die Fehlerbehandlung ist fehlerhaft, weil wenn bind nicht funktioniert, ist das Programm nicht mehr in einem sinnvollen Zustand, Du machst aber weiter, als ob alles funktioniert hätte.

dataTransfer: TCP-Verbindungen sind Ströme, es gibt keine Nachrichtengrenzen, daher ist das Lesen falsch. Du mußt bei recv immer damit rechnen, dass pro Aufruf nur 1 Byte kommt. Du schließt zwar die Sockets, beendest aber die Endlosschleife nicht, das führt automatisch zu einer Exception beim nächsten Schleifendurchlauf.
Antworten