ich habe einen TCP-Server laufen.
Damit <TCPsever.accept()> und <client_socket.recv(1024)> nicht zum blockieren des Codes führen laufen diese einem thread.
Das funktioniert soweit auch sehr gut.
Code: Alles auswählen
class Server(threading.Thread):
def __init__(self, GA_callback, iFrame_callback, ip, port,):
self.GA_callback = GA_callback
self.iFrame_callback = iFrame_callback
#TCP-Server
self.IP = ip
self.port = port
self.TCPsever = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.TCPsever.bind((self.IP, self.port))
self.TCPsever.listen(5) # max backlog of connections
threading.Thread.__init__(self)
self.running = True
self.start()
def run(self): #threat running continuously
while self.running:
self.client_socket, address = self.TCPsever.accept() #waiting for client
self.handle_client_connection(self.client_socket)
#--- handle client Rx-Data ------------------------------------------------
def handle_client_connection(self, client_socket):
try:
while True:
try:
request = client_socket.recv(1024)
except Exception as inst:
client_socket.close()
break
if not request:
client_socket.close()
break
else:
#I-Frame
if request[2] & 0b00000001 == 0b0: #.0 I-Frame #_0 I-Frame
self.RxCounter += 1
self.handle_iFrame(request, client_socket, cmEngine_id)
finally:
client_socket.close()
Auch die Callbacks funktionieren einwandfrei.
Mein Problem ist jetzt ein win32com-object.
Im Hauptprogramm wird ein win32com Objekt instanziiert.
Im Hauptprogramm gibt es Funktionen für den Zugriff auf das win32com-Objekt.
Die Funktion für den Zugriff auf das win32com-Objekt soll nur durch die Callbackfunktionen aufgerufen werden.
Code: Alles auswählen
import win32com.client # get e.g. via "pip install pywin32"
cmEngine = win32com.client.Dispatch("OMICRON.CMEngAL")
def on_IEC60870_5_104_I_Frame_received_callback(APDU):
if APDU.ASDU.InfoObject.address.DEZ == 1:
doFromThread()
def doFromThread():
global cmEngine
print(cmEngine.DevScanForNew(False)) <---- Fehler
print(cmEngine.DevGetList(0))
Bei Aufruf des win32com-Objektes kommt es zu einem Fehler, den ich nicht zu 100% eingrenzen konnte.
Nach meinen Recherchen scheint es mit dem Aufruf des win32com-Objektes aus dem Server-thread zu liegen.
Ich habe schon versucht mich im die <pythoncom> Routinen einzulesen.
(cmEngine_id = pythoncom.CoMarshalInterThreadInterfaceInStream(pythoncom.IID_IDispatch, cmEngine))
(pythoncom.CoInitialize())
(cmEngine= win32com.client.Dispatch(pythoncom.CoGetInterfaceAndReleaseStream(cmEngine_id , pythoncom.IID_IDispatch))
Hier werden die Referenzen (IDs) zum win32com-Objekt mit durchgereicht.
Leider enden meine Fähigkeiten an dieser Stelle.
Daher 2 Fragen:
Wie baut man einen TCP-Server "richtig" auf.
Der Server sollte den Code nicht blockieren.
- Wie baut man einen TCP-Server "richtig" auf?
Der Server sollte den Code nicht blockieren. - Wie kann ich ein win32com-Objekt über einen Callback aus einem thread gültig aufrufen?
Pf@nne