Socket und Thread mit Button schließen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
DMD-OL
User
Beiträge: 104
Registriert: Samstag 26. Dezember 2015, 16:21

Socket und Thread mit Button schließen

Beitragvon DMD-OL » Samstag 10. Dezember 2016, 18:42

hi
ich versuche grad verzweifelt meinen socket und Thread mithilfe eines Buttons zu schließen.
Wenn ich das Programm starte kann ich mich normal anmelden, Daten übertrage... Läuft.
Wenn ich allerdings das Programm mit BEENDEN schließe, kann ich mich zunächst nicht mehr mit
meiner App auf meinem Handy anmelden (funktioniert auch :)), aber sobald ich das Programm
dann erneut starte, wird eine neue Verbindung angezeigt, mein Handy kann sich aber noch
mit der alten IP-Adresse und Port anmelden :(
Ich möchte, daß das nicht mehr geht.
D.h. wenn ich das Programm beende, will ich mich nur mit der aktuell geöffneten Verbindung
verbinden können, eine alte Verbindung soll durch Klick auf den Button getötet werden.
Ich brauch da Hilfe von außerhalb, da ich schon ziemlich alles durchhabe im Netz.
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import Tkinter
  4. import threading
  5. import socket
  6. import sys
  7.  
  8. class Testarea():
  9.  
  10.     def main(self):
  11.  
  12.         stop_threads = False
  13.         workers = []
  14.  
  15.         root = Tkinter.Tk()
  16.         root.title('DMD-DATA.soft')
  17.         root.geometry('700x500+385+200')
  18.         root.configure(background='black')
  19.         start_Server = Tkinter.StringVar()
  20.         l_sf1 = Tkinter.Label(root,textvariable=(start_Server),font=('Arial', 8, 'bold'), height=3, width=25, fg="#000000000",justify='left')
  21.         l_sf1.place(relx=.15, rely=.9, anchor="c")
  22.  
  23.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  24.         sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  25.  
  26.         def run(sock,start_Server,stop):
  27.             while True:
  28.  
  29.                 get_IP = [TCP_IP for TCP_IP in socket.gethostbyname_ex(socket.gethostname())[2] if not TCP_IP.startswith("127.")][:1]
  30.                 if TCP_IP.startswith("127."):
  31.                     start_Server.set("KEIN W-LAN!")
  32.                     start_Client.set("Um Daten übertragen zu können,\nmuß W-LAN vorhanden sein!")
  33.                 else:
  34.                     server_address = ((TCP_IP, 0))
  35.                     sock.bind(server_address)
  36.                     TCP_PORT = sock.getsockname()[1]
  37.                     ipPort = "IP-Adresse: "+str(TCP_IP)+"\n                  Port: "+str(TCP_PORT)
  38.                     start_Server.set("SERVER GESTARTET:\n     "+ipPort)
  39.                     sock.listen(5)
  40.                     while True:
  41.                         client,addr = sock.accept()
  42.                         client.send("Hallo, mein Nmae")
  43.                         data = client.recv(1024)
  44.                         print data
  45.                         client.close()
  46.                 sock.close()
  47.  
  48.                 if stop():
  49.                     break
  50.  
  51.         new_thread = threading.Thread(target=run,args=(sock,start_Server,lambda:stop_threads))
  52.         new_thread.start()
  53.  
  54.         print"Thread gestartet..."
  55.  
  56.         def beenden(sock,stop_threads):
  57.             sock.close()
  58.             stop_threads = True
  59.             print("Thread beendet.")
  60.             root.destroy()
  61.             sys.exit(1)
  62.  
  63.         b2 = Tkinter.Button(root, text=("\nBEENDEN\n"), font=('Arial', 10, 'bold'), width=20, relief="raised", borderwidth=3, fg='#000000000', justify='center',command=lambda:beenden(sock,stop_threads))
  64.         b2.place(relx=.51, rely=.52, anchor="c")
  65.  
  66.         root.mainloop()
  67.  
  68. test = Testarea()

Nach dem zweiten Öffnen des Threadservers, verbindet sich das Handy einfach so oft ich auf Senden gedrückt habe,
die Daten werden dann genau so oft rübergesendet :(
und ich erhalte einmal in blauer Schrift die gesendeten Daten und
in rot eine Fehlermeldung:

Code: Alles auswählen

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\Lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "C:\Python27\Lib\threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "C:\Users\DMD-OL\Documents\Pythoncode\module1.py", line 41, in run
    client,addr = sock.accept()
  File "C:\Python27\Lib\socket.py", line 206, in accept
    sock, addr = self._sock.accept()
  File "C:\Python27\Lib\socket.py", line 174, in _dummy
    raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor

Thread gestartet...

ICH KANN AUCH NICHT MEHR!
Zuletzt geändert von BlackJack am Samstag 10. Dezember 2016, 19:51, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 5260
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Socket und Thread mit Button schließen

Beitragvon Sirius3 » Montag 12. Dezember 2016, 13:44

@DMD-OL: das wird hier nicht besser. In Deinen anderen Threads ignorierst Du ja meine Korrekturen. Und nochmal einen neuen Thread mit dem gleichen Thema aufzumachen, bringt ja auch nicht wirklich was. Lies doch mal meine Kommentare und arbeite sie mal in ein Programm ein, dann kommen wir hier vielleicht weiter.

Nochmal zur Zusammenfassung: eine Klasse die nur aus einer Methode besteht ist keine. Es gibt einen unterschied zwischen lokalen und nicht-lokalen Variablen. Du mischt hier z.B. bei stop_threads alles durcheinander und wunderst Dich, warum das nicht so tut, wie Du hoffst. Daher: definier **keine** verschachtelte Funktionen, das macht den Code unlesbar! sock ist außerhalb von run definiert. Was soll das? get_IP und der ganze ich such nach WLAN-Schrott ist und bleibt Schrott, weg damit! Setz einen festen Port. Dass Du damit nicht zurecht kommst, liegt daran, dass Du Deine Programme nicht sauber beendest. Aber das Problem hatte ich schonmal gelöst. Lies das einfach mal nach! (Stichwort Dämon). Stringzusammenstücklung mit + und str-Aufrufe mit Strings durch .format ersetzen. client.recv funktioniert so nicht. TCP ist ein Streaming Protocol. Erzeug Dir am besten ein Filehandle mit makefile.

Du kannst gerne, wenn Du was nicht verstanden hast, nachfragen. Aber hör bitte auf, die selben Fehler, die ich jedes mal wieder anmeckere wieder in einer anderen Variante hier zu posten. Ich komme mir damit nämlich verarscht vor.

Zurück zu „Netzwerkprogrammierung“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder