FB_UDPPeer

Panoramica

Tipo:

Blocco funzione

Disponibile a partire da:

V1.0.4.0

Ereditato da:

-

Implementa:

-

G-SE-0045960.1.gif-high.gif

 

 

Task

Rappresenta un punto finale per la ricezione e invio di messaggi utilizzando un protocollo UDP per messaggi.

Descrizione funzionale

L'ordine normale del comando è quello di richiamare prima il metodo Open. Se questo riesce, i messaggi possono essere inviati. Se si intende ascoltare su una porta specifica occorre utilizzare il metodo Bind per collegare il socket a questa porta e opzionalmente a una interfaccia Ethernet specifica. Se i messaggi devono essere ricevuti su tutte le interfacce Ethernet disponibili e l'interfaccia di uscita deve essere utilizzata automaticamente, utilizzare una stringa vuota oppure 0.0.0.0 come ingresso-interfaccia del metodo.

Per inviare dati a un altro peer, usare il metodo Send. Al primo invio da un socket non associato, esso viene associato automaticamente e successivamente può essere utilizzato il metodo Receive. Se il runtime lo supporta, si può richiedere l'IP e la porta a cui è stato associato il socket utilizzando le proprietà BoundIPAddress e BoundPort.

Per verificare se vi sono dati pronti da leggere, possono essere utilizzate le proprietà IsReadable e BytesAvailableToRead.

Per entrambi i metodi Send e Receive deve essere fornito un buffer dall'applicazione che verrà riempito dal metodo Received e che contiene i dati da inviare dal metodo Send.

I broadcast possono essere inviati e ricevuti senza alcuna preparazione. Per poter ricevere messaggi multicast, deve essere aggiunto un gruppo multicast. Per questo motivo, sono forniti i metodi JoinMulticastGroup e LeaveMulticastGroup.

Se si desidera inviare pacchetti multicast UDP usando il blocco funzione FB_UDPPeer, impostare il valore della proprietà SockOpt_MulticastDefaultInterface sull'indirizzo IP dell'interfaccia da cui devono essere inviati i pacchetti. Questa operazione deve essere eseguita dopo aver chiamato il metodo Open e prima di chiamare per la prima volta il metodo SendTo.

NOTA: Specificando l'interfaccia predefinita per pacchetti multicast tramite il valore della proprietà SockOpt_MulticastDefaultInterface, si evita che i pacchetti vengano inviati a tutta la rete disponibile.

Il metodo Close può essere utilizzato per interrompere un ulteriore invio di dati e chiudere il socket.

Se l'elaborazione in un metodo non riesce, questo viene indicato nel valore della proprietà Result. Il valore di Result deve essere verificato dopo ogni chiamata di un metodo. Il risultato può essere reimpostato a Ok utilizzando il metodo ResetResult.

NOTA: Tutti i metodi sono bloccati finché il valore della proprietà Result è diverso da Ok. Una chiamata di metodo in questo caso viene interrotta senza toccare le informazioni della proprietà Result.

Interfaccia

 Il blocco funzione non ha ingressi e uscite. La funzionalità è disponibile attraverso i metodi e le proprietà. Non è necessario richiamare il blocco funzione direttamente nell'applicazione.

Esempi di implementazione

I seguenti esempi di applicazione indicano come associarsi a un gruppo multicast e inviarvi un messaggio:

Peer1:

PROGRAM Peer1
VAR
    //Commands
    xOpen : BOOL ;
    xSend : BOOL ;
    xClose : BOOL ;
    //UDP peer1 instance
    fbUdpPeer1 : TCPUDP.FB_UDPPeer ;
    //Peer1 state
    etResult : TCPUDP.ET_State ;
    etState : TCPUDP.ET_Result ;
    //Application parameters
    iState : INT ;
    sSendMessage : STRING ;
    //Connection parameters peer1
    sIpAddressLocal : STRING := '120.120.120.13' ; //IP
    //Multicast group parameters
    sMulticastIP : STRING := '224.0.1.38' ; //Unassigned multicast IP
    uiPortPeer2 : UINT := 8002 ; //Port of peer2 joined to multicast group
END_VAR

CASE iState OF
    0 : //idle
        IF xOpen THEN
            fbUdpPeer1.Open ( ) ;
            IF fbUdpPeer1.State = TcpUdp.ET_State.Opened THEN
                //opened
                fbUdpPeer1.SockOpt_MulticastDefaultInterface := sIpAddressLocal ; //IP address of the interface from which the packages should be sent
                iState := 20 ;
            ELSE
                iState := 100 ; //error detected
            END_IF
        END_IF
    20 : //opened
        IF xSend THEN //Send from peer1 to multicast group
            sSendMessage := 'Hello world!' ;
            fbUdpPeer1.SendTo ( i_pbySendBuffer := ADR (sSendMessage ) ,
            i_udiNumBytesToSend := INT_TO_UDINT ( LEN ( sSendMessage ) ) ,
            i_sPeerIP := sMulticastIP ,
            i_uiPeerPort := uiPortPeer2 ) ;
        IF fbUdpPeer1.Result <> TcpUdp.ET_Result.Ok THEN
            iState := 100 ; //error detected
        END_IF
    ELSIF xClose THEN
        fbUdpPeer1.Close ( ) ;
        IF fbUdpPeer1.State = TcpUdp.ET_State.Idle THEN
            iState := 0 ; //closed = idle
        ELSE
            iState := 100 ; //error detected
        END_IF
        END_IF
    100 : //error state
        (*your code comes here*)
END_CASE
//check cyclically state
etResult := fbUdpPeer1.State ;
etState := fbUdpPeer1.Result ;
//reset commands
xOpen := xSend := xClose := FALSE ;

Peer2:

PROGRAM Peer2
VAR
    //Commands
    xOpenAndBind : BOOL ;
    xJoinMulticastGroup : BOOL ;
    xReceive : BOOL ;
    xClose : BOOL ;
    //UDP Peer2 instance
    fbUdpPeer2 : TCPUDP.FB_UDPPeer ;
    //Peer2 state
    etResult : TCPUDP.ET_State ;
    etState : TCPUDP.ET_Result ;
    //Application parameters
    iState : INT ;
    sReceiveMessage : STRING ;
    //Connection parameters Peer2
    sIpAddressLocal : STRING ;= '120.120.120.13' ; //IP
    uiPortLocal : UINT := 8002 ; //Port
    //Multicast group parameters
    sMulticastIP : STRING ;= '224.0.1.38' ; //Unassigned multicast IP
END_VAR

CASE iState OF
    0 : //idle
        IF xOpenAndBind THEN
            //open
            fbUdpPeer2.Open ( ) ;
            IF fbUdpPeer2.State = TcpUdp.ET_State.Opened THEN
                fbUdpPeer2.Bind ( i_sLocalIP := '' , i_uiLocalPort := uiPortLocal ) ; //opened... now bind
                IF fbUdpPeer2.State = TcpUdp.ET_State.Bound THEN
                    iState := 20 ; //bound
                END_IF
            END_IF
            IF fbUdpPeer2.Result <> TcpUdp.ET_Result.Ok THEN
                iState := 100 ; //error detected
            END_IF
        END_IF
    20 : //bound
        IF xJoinMulticastGroup THEN
            fbUdpPeer2.JoinMulticastGroup ( i_sInterfaceIP := sIpAddressLocal , i_sGroupIP := sMulticastIP ) ;
                IF fbUdpPeer2.Result <> TcpUdp.ET_Result.Ok THEN
                    iState := 100 ; //error detected
                END_IF
            ELSIF xReceive THEN
                //Receive message
                fbUdpPeer2.ReceiveFrom ( i_pbyReceiveBuffer := ADR ( sReceiveMessage ) ,
                        i_udiReceiveBufferSize := SIZEOF ( sReceiveMessage ) ) ;
                IF fbUdpPeer2.Result <> TcpUdp.ET_Result.Ok THEN
                    iState := 100 ; //error detected
                END_IF
            ELSIF xClose THEN
                fbUdpPeer2.Close ( ) ;
                IF fbUdpPeer2.State = TcpUdp.ET_State.Idle THEN
                    iState := 0 ; //closed = idle
                ELSE
                    iState := 100 ; //error detected
                END_IF

            END_IF

        100 : //error state
            (*your code comes here*)
END_CASE
//check cyclically state
etResult := fbUdpPeer2.State ;
etState := fbUdpPeer2.Result ;
//reset commands
xOpenAndBind := xJoinMulticastGroup := xReceive := xClose := FALSE ;