Tipo: |
Blocco funzione |
Disponibile a partire da: |
V1.0.4.0 |
Ereditato da: |
- |
Implementa: |
- |
Rappresenta un punto finale per la ricezione e invio di messaggi utilizzando un protocollo UDP per messaggi.
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.
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.
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 ;