erstmal ein herzliches Hallo an das Forum, denn ich bin neu hier.
Kurzer Hintergrund: An Python bin ich geraten da ich Skripte zur Hausautomation in meinen Webanwendungen verwende. Hierfür ist auch der Zugriff auf Datenbanken notwendig...
Mein Problem:
Ich habe zur schnelleren Anbindung an die mariadb auf meinem Synology-Server einen kleinen Socketserver programmiert, der die Abfragen aus den Webzugriffen über mysql.connector an die Datenbank weitergibt und die Ergebnisse an den Client zurückgibt. Das Funktioniert auch alles so wie ich mir das gewünscht habe. ABER wenn ich mit server.shutdown() den Server beende, können meine Clients zwar nicht mehr darauf zugreifen, aber ich kann den Server nicht mehr neu starten. Obwohl der Socketserver "beendet" ist, läuft der Prozess noch auf meinem Synology-Server! Somit kommt die Fehlermeldung, dass der Port bereits vergeben ist. Erst nachdem ich den Prozess mit "kill" herausschmeisse kann ich den Socketserver wieder neu starten.
Daher meine Frage. Wie beende ich einen Socketserver inkl. Beenden des Prozesses korrekt?
So sieht mein Server-Code aus:
Code: Alles auswählen
#!/usr/bin/python3
from time import time
from module._config import config
from module.log import *
import mysql.connector as mysql
import socketserver
import pickle
class MyUDPHandler(socketserver.BaseRequestHandler):
def handle(self):
daten=self.request[0].strip()
s= self.request[1]
addr =self.client_address
if daten==b".stop":
s.sendto(b"Der DB-Server wird gestoppt, Datenbank wird geschlossen.:END",addr)
db_log("Server wird gestoppt")
warnung("Der Server und die Datenbank wurden geschlossen!","Server")
server.shutdown()
conn.close()
else:
data=pickle.loads(daten)
if data[0][:6]=="SELECT":
datasend=db_select(*data)
elif data[0]=="log":
datasend=db_log(*data[1])
else:
datasend=db_comm(*data)
datasend=datasend+b":END"
if len(datasend)<1025:
s.sendto(datasend,addr)
else:
x=int(len(datasend)/1024)
for y in range (x+1):
if y==x+1:
s.sendto(datasend[y*1024:],addr)
else:
s.sendto(datasend[y*1024:(y+1)*1024],addr)
def db_log (T,W=0,Z=time(),Wa="Server",B="Privat"):
return(db_comm("INSERT INTO Ereignisse (Warnung,Zeit,Webarea,Bereich,Text) VALUES (%s,%s,%s,%s,%s)",(W,Z,Wa,B,T)))
def db_comm(comm,value):
try:
c=conn.cursor()
c.execute(comm,value)
conn.commit()
c.close()
return(pickle.dumps("OK"))
except:
return(pickle.dumps("Fehler"))
def db_select(comm,value):
try:
c=conn.cursor()
c.execute(comm,value)
data=c.fetchall()
c.close()
return(pickle.dumps(data))
except:
return(pickle.dumps("Fehler"))
if __name__=="__main__":
with open(config("db.pw"), "r") as z:
zugang=[line.strip() for line in z]
db_log("Datenbank wird geöffnet")
try:
conn=mysql.connect(host=zugang[0],user=zugang[1],password=zugang[2], database=zugang[3])
db_log("Server wird gestartet")
server = socketserver.UDPServer(("127.0.0.1", 55072), MyUDPHandler)
server.serve_forever()
except:
warnung("Fehler im Server oder Datenbank!","Server")
finally:
server.shutdown()
server.close()
warnung("Der Server und die Datenbank wurden geschlossen!","Server")
Wenn ich also. ".stop" sende erscheinen alle richtigen Meldungen, der Server ist mit meinem Client auch nicht mehr erreichbar, ABER der Prozess ist noch aktiv.
Der Vollständigkeit wegen hier noch der Client-Code zum Beenden des Servers:
Code: Alles auswählen
#!/usr/bin/python3
import cgitb; cgitb.enable()
from module.html import *
import socket
ip="127.0.0.1"
port=55072
data=b""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(1)
try:
s.sendto(b".stop",(ip,port))
while True:
data+=(s.recv(1024))
if b":END" in data:
break
x=data[:-4].decode()
except:
x="Keine Verbindung zum Server"
finally:
s.close()
html_start("white")
print(x)
html_end()
Dirk