====== UdpClientServer - Bidirectional ====== [[http://www.openhardsoftware.de/ | Open Hard- & Software]] [ [[http://www.openhardsoftware.de/dokuwiki | DokuWiki]] [[http://www.openhardsoftware.de/websites | WebSites]] [[http://www.openhardsoftware.de/mediawiki | MediaWiki]] [[http://www.openhardsoftware.de/nextcloud | NextCloud]] ] Bidirektionales Senden und Empfangen von UDP-Datenpaketen (OOP, Threading, NoBlocking) ===== Benutzung ===== * Bidirektionaler Datenaustausch zwischen UdpClient und UdpServer vv. * Udp-Datenaustausch auf einem bzw. zwischen zwei PCs * UdpClient ohne Blocking * Identische SourceCodes in zwei Terminals mit unterschiedlichen Übergabe-Parametern Aufruf in der Kommandozeile mit Argumenten: \\ ** python CheckUdpClientServer.py ** \\ \\ Beispiel: >python CheckUdpClientServer.py PCID 5555 192.168.178.123 4444 ==== Single PC: Aufruf ohne Übergabe-Parameter: ==== >python UdpClientServer.py *** UdpClientServer: begin UDPHID: TxIP-Address[127.0.0.255]-Port[5000] UDPHID: RxIP(local)-Address[192.168.178.33]-Port[5000] CBOnTxData[UDPHID]<0> CBOnTxData[UDPHID]<1> CBOnTxData[UDPHID]<2> *** UdpClientServer: end ==== Single PC: Aufruf mit Übergabe-Parametern ==== * Sender / Empfänger mit identischer IPAddress[192.168.178.33](lokal) * Rx-Port[4321] und Tx-Port[4321] identisch >python UdpClientServer.py Windows 4321 192.168.178.33 4321 *** UdpClientServer: begin Windows: TxIP-Address[192.168.178.33]-Port[4321] Windows: RxIP(local)-Address[192.168.178.33]-Port[4321] CBOnTxData[Windows]<0> CBOnRxData[Windows]<0> CBOnTxData[Windows]<1> CBOnRxData[Windows]<1> CBOnTxData[Windows]<2> CBOnRxData[Windows]<2> *** UdpClientServer: end ==== Single PC: Aufruf an alle UdpReceiver ==== * Sendung an alle IPAddresses[192.168.178.255] (auch an sich selbst!) * Rx-Port[4321] und Tx-Port[4321] identisch >python UdpClientServer.py Windows 4321 192.168.178.255 4321 *** UdpClientServer: begin Windows: TxIP-Address[192.168.178.255]-Port[4321] Windows: RxIP(local)-Address[192.168.178.33]-Port[4321] CBOnTxData[Windows]<0> CBOnRxData[Windows]<0> CBOnTxData[Windows]<1> CBOnRxData[Windows]<1> CBOnTxData[Windows]<2> CBOnRxData[Windows]<2> *** UdpClientServer: end ==== Dual PC: ==== === WindowPC[192.168.178.33] === >python CheckUdpClientServer.py Windows 5001 192.168.178.48 5000 *** CheckUdpClientServer: begin Windows: TxIP-Address[192.168.178.48]-Port[5000] Windows: RxIP(local)-Address[192.168.178.33]-Port[5001] CBOnRxData[Windows]<0[Ubuntu]> CBOnTxData[Windows]<0[Windows]> CBOnRxData[Windows]<1[Ubuntu]> CBOnTxData[Windows]<1[Windows]> CBOnRxData[Windows]<2[Ubuntu]> CBOnTxData[Windows]<2[Windows]> CBOnRxData[Windows]<3[Ubuntu]> CBOnTxData[Windows]<3[Windows]> CBOnRxData[Windows]<4[Ubuntu]> CBOnTxData[Windows]<4[Windows]> CBOnRxData[Windows]<5[Ubuntu]> CBOnTxData[Windows]<5[Windows]> *** CheckUdpClientServer: end === UbuntuPC[192.168.178.48] === >python CheckUdpClientServer.py Ubuntu 5000 192.168.178.33 5001 *** CheckUdpClientServer: begin Ubuntu: TxIP-Address[192.168.178.33]-Port[5001] Ubuntu: RxIP(local)-Address[192.168.178.48]-Port[5000] CBOnTxData[Ubuntu]<0[Ubuntu]> CBOnTxData[Ubuntu]<1[Ubuntu]> CBOnRxData[Ubuntu]<0[Windows]> CBOnTxData[Ubuntu]<2[Ubuntu]> CBOnRxData[Ubuntu]<1[Windows]> CBOnRxData[Ubuntu]<2[Windows]> CBOnTxData[Ubuntu]<3[Ubuntu]> CBOnRxData[Ubuntu]<3[Windows]> CBOnTxData[Ubuntu]<4[Ubuntu]> CBOnRxData[Ubuntu]<4[Windows]> CBOnTxData[Ubuntu]<5[Ubuntu]> *** CheckUdpClientServer: end ===== Hauptprogramm: CheckUdpClientServer.py ===== # # Syntax-Arguments: # # WindowsPC[192.168.178.33] <-> # WindowsPC[192.168.178.33]: # WinPC: python CheckUdpClientServer.py Windows 4321 192.168.178.33 4321 # # WindowsPC[192.168.178.33] <-> UbuntuPC[192.168.178.48] # WinPC: python CheckUdpClientServer.py Windows 5001 192.168.178.48 5000 # LinPC: python CheckUdpClientServer.py Ubuntu 5000 192.168.178.33 5001 # import sys import time import socket as SKT # import Thread as THR import UdpClientServer as UCS # UDP_HEADERID = 'UDPHID' #----------------------------------------------------------- # UDP - TxD - TransmitData #----------------------------------------------------------- UDP_IPADDRESS_TX = '127.0.0.255' UDP_IPPORT_TX = 5000 # #----------------------------------------------------------- # UDP - RxD - ReceiveData #----------------------------------------------------------- UDP_IPADDRESS_LOCAL = '127.0.0.1' # dummy UDP_IPPORT_RX = 5000 # #----------------------------------------------------------- # Callback - UdpClient #----------------------------------------------------------- def CBOnTxData(udpclientserver, txdata): Line = 'CBOnTxData[{}]<{}>'.format(udpclientserver.GetHeaderID(), txdata) print(Line) return # def CBOnRxData(udpclientserver, rxdata): Line = 'CBOnRxData[{}]<{}>'.format(udpclientserver.GetHeaderID(), rxdata) print(Line) return # def CBOnStart(udpclientserver): # debug print('Main-CBOnStart') return # def CBOnBusy(udpclientserver): # debug print('Main-CBOnBusy') return # def CBOnAbort(udpclientserver): # debug print('Main-CBOnAbort') return # def CBOnEnd(udpclientserver): # debug print('Main-CBOnEnd') return # #----------------------------------------------------------- # Main #----------------------------------------------------------- if ('__main__' == __name__): # print('*** CheckUdpClientServer: begin') if (5 <= len(sys.argv)): # Analyse Arguments für Tx/Rx-Parameter UDP_HEADERID = sys.argv[1] # RX UDP_IPPORT_RX = int(sys.argv[2]) # TX UDP_IPADDRESS_TX = sys.argv[3] UDP_IPPORT_TX = int(sys.argv[4]) # UdpCS = UCS.CUdpClientServer(UDP_HEADERID, UDP_IPPORT_RX, UDP_IPADDRESS_TX, UDP_IPPORT_TX, CBOnTxData, CBOnRxData, CBOnStart, CBOnBusy, CBOnAbort, CBOnEnd) # print('{}: TxIP-Address[{}]-Port[{}]'.format(UdpCS.GetHeaderID(), UdpCS.GetIPAddressTX(), UdpCS.GetIPPortTX())) print('{}: RxIP(local)-Address[{}]-Port[{}]'.format(UdpCS.GetHeaderID(), UdpCS.GetIPAddressRXLocal(), UdpCS.GetIPPortRX())) UdpCS.Open() for I in range(0, 3): time.sleep(5.0) UdpCS.Transmit('{}'.format(I)) time.sleep(1.0) UdpCS.Close() # print('*** CheckUdpClientServer: end') # # ===== Class-Library: UdpClientServer.py ===== # import time import enum as ENU import socket as SKT # import Thread as THR # class CUdpClientServer(): # def __init__(self, headerid, ipportrx, \ ipaddresstx, ipporttx, \ ontxdata, onrxdata, \ onstart, onbusy, onabort, onend): self.HeaderID = headerid self.IPAddressRXLocal = '' self.IPPortRX = ipportrx self.IPAddressTX = ipaddresstx self.IPPortTX = ipporttx self.OnTxData = ontxdata self.OnRxData = onrxdata self.OnStart = onstart self.OnBusy = onbusy self.OnAbort = onabort self.OnEnd = onend self.Thread = THR.CThread(self.CBOnStart, self.CBOnBusy, \ self.CBOnAbort, self.CBOnEnd) self.RxSocket = None self.TxSocket = None # find local IPAddress: S = SKT.socket(SKT.AF_INET, SKT.SOCK_DGRAM) S.connect(('8.8.8.8', 1)) self.IPAddressRXLocal = S.getsockname()[0] S.close() # return # def GetHeaderID(self): return self.HeaderID def GetIPAddressTX(self): return self.IPAddressTX def GetIPPortTX(self): return self.IPPortTX def GetIPAddressRXLocal(self): return self.IPAddressRXLocal def GetIPPortRX(self): return self.IPPortRX # def IsBusy(self): return THR.EStateThread.stBusy == self.Thread.State # def Open(self): # Rx if (THR.EStateThread.stBusy == self.Thread.State): self.Thread.Abort() self.RxSocket = SKT.socket(SKT.AF_INET, SKT.SOCK_DGRAM) # FORWARD Socket.bind !!! self.RxSocket.setsockopt(SKT.SOL_SOCKET, SKT.SO_REUSEADDR, 1) self.RxSocket.bind((self.IPAddressRXLocal, self.IPPortRX)) self.RxSocket.setblocking(0) self.Thread.Start() # Tx self.TxSocket = SKT.socket(SKT.AF_INET, SKT.SOCK_DGRAM) self.TxSocket.connect((self.IPAddressTX, self.IPPortTX)) return # def Close(self): self.Thread.Abort() self.RxSocket.close() self.TxSocket.close() # def Abort(self): self.Thread.Abort() return # def Transmit(self, text): if (None != self.OnTxData): self.OnTxData(self, text) self.TxSocket.sendto(text.encode('utf-8'), \ (self.IPAddressTX, self.IPPortTX)) # def CBOnStart(self, thread): if (None != self.OnStart): self.OnStart(self) return # def CBOnBusy(self, thread): while self.IsBusy(): RxData = '' try: Data, Address = self.RxSocket.recvfrom(1024) RxData = Data.decode('utf-8') except SKT.error: pass else: # print('RxData[{}]'.format(Data.decode('utf-8'))) if (None != self.OnRxData): self.OnRxData(self, RxData) finally: time.sleep(0.1) if (None != self.OnBusy): self.OnBusy(self) self.RxSocket.close() return # def CBOnAbort(self, thread): self.RxSocket.close() if (None != self.OnAbort): self.OnAbort(self) return # def CBOnEnd(self, thread): self.RxSocket.close() if (None != self.OnEnd): self.OnEnd(self) return # # ===== Class-Library: Thread.py ===== # import time import threading as THD import enum as ENU # class EStateThread(ENU.Enum): stIdle = 0 stBusy = 1 stEnd = 2 # def CBOnExecute(thread): if (None != thread.OnBusy): thread.OnBusy(thread) if (None != thread.OnEnd): thread.OnEnd(thread) return # class CThread(): # def __init__(self, onstart, onbusy, onabort, onend): self.State = EStateThread.stIdle self.Thread = THD.Thread(target=CBOnExecute, args=(self,)) self.OnStart = onstart self.OnBusy = onbusy self.OnAbort = onabort self.OnEnd = onend return # def Start(self): self.State = EStateThread.stBusy if (None != self.OnStart): self.OnStart(self) self.Thread.start() return # def Abort(self): self.State = EStateThread.stEnd if (None != self.OnAbort): self.OnAbort(self) return # # ===== Version ===== {{:module:python:UdpClientServer:2112112117_UdpClientServer_02V01.zip|2112112117_UdpClientServer_02V01.zip}} ----- [[http://www.openhardsoftware.de/ | Open Hard- & Software]] [ [[http://www.openhardsoftware.de/dokuwiki | DokuWiki]] [[http://www.openhardsoftware.de/websites | WebSites]] [[http://www.openhardsoftware.de/mediawiki | MediaWiki]] [[http://www.openhardsoftware.de/nextcloud | NextCloud]] ]