Table of Contents

UdpClientServer - Bidirectional

Open Hard- & Software [ DokuWiki WebSites MediaWiki NextCloud ]

Bidirektionales Senden und Empfangen von UDP-Datenpaketen (OOP, Threading, NoBlocking)

Benutzung

Aufruf in der Kommandozeile mit Argumenten:
python CheckUdpClientServer.py <headerid> <rxipport> <txipaddress> <txipport>

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

>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

>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: <headerid> <rxipport> <txipaddress> <txipport>
#
# 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

2112112117_UdpClientServer_02V01.zip


Open Hard- & Software [ DokuWiki WebSites MediaWiki NextCloud ]