UDPSocket
Use the UdpSocket commands to send and receive data over a UdpSocket connection.
Static class method. Creates a new instance of the UdpSocket class.
Syntax
UdpSocket.New()
Arguments
None.
Returns
UdpSocket object.
Opens the UdpSocket. Optionally bind to a local IP and Port (either or both).
Syntax
Open( <IP>, <Port> )
Arguments
IP : String. Optional. The local IP address that the connection should use. If not specified, UDP would be sent from a single IP address based on the connected LAN ports. This selection is made based on network conditions. The LAN connection outputting UDP data may change as LAN connections to the Core are changed. Makes no difference in receiving.
Port : Integer, 0 - 65535. Optional. The local Port that the connection should use. If not specified, the port is selected by the system.
Closes an open UdpSocket on a specified port.
Syntax
Close( )
Arguments
None.
Sends data to IP Address and port.
Syntax
Send( IP_Address, Port, Data )
Arguments
IP_Address : String. IP Address to send to.
Port : Integer, 0 - 65535. The port to send to.
Data : String, up to 65535 bytes. Binary data, represented in Lua as a string.
Joins the multicast address, binding to local IP.
Note: If there are multiple NICs present (failover systems and redundant systems), you need to specify the local IP for the JoinMulticast()
method to ensure proper recovery on system stop/start up.
Syntax
JoinMulticast( Address, <Local_IP>)
Arguments
Address : String. Multicast IP Address to receive packets from.
Local_IP : String. Local IP address to bind to. This is an optional argument for single NIC systems, otherwise QDS will randomly choose a NIC to receive packets from and might not be the correct one in a multi-NIC system.
Name |
Description |
---|---|
EventHandler |
Function to call when UDP packet is received. The signature of function is 'function(socket, data)' data is a table consisting of the following:
|
.MulticastTtl |
A number from 0 to 255. Default is 1. Changes the multicast time-to-live (TTL) value in multicast UDP packets sent from Lua. The TTL value can be set before the socket is opened and can also be changed dynamically while the socket is in use. |
Optional callback functions may be defined instead of using the singular EventHandler. Depending upon the application, defining separate functions for each event may be preferable. The choice to use either a single EventHandler to capture all socket events or separate callback functions is up to the programmer. There is no need to change a functioning script because this new functionality exists and you may choose to never use it. But some programmers may feel that the callback method better matches their logical style.
Name |
Function Signature |
Description |
---|---|---|
.Data |
function( udpTable, data )' data is a table consisting of the following:
|
Assign a function which is called when data is received. See Example 3: Using the UdpSockets Callback method. |
-- receiving multicast
-- (Port 2468 is the port for the Q-SYS Core's IO device queries sent every two seconds)
udp = UdpSocket.New() --Create new UDP object
udp.EventHandler = function(udp, packet)
print( packet.Address, packet.Port, packet.Data )
end
udp:Open( "192.168.1.100", 2468 ) -- IP address is optional
udp:JoinMulticast("224.0.23.175") -- Sends a multicast join report for the multicast address
local udp = UdpSocket.New()
udp:Open()
udp:Send(
"224.0.23.175",
2467,
"<QDP><query_ref>device.ioframe.*</query_ref></QDP>" )
udp = UdpSocket.New() --Create new UDP object
udp.Data = function(udp, packet)
print( packet.Address, packet.Port, packet.Data )
end
udp:Open( "192.168.1.100", 2468 ) -- IP address is optional
udp = UdpSocket.New()
udp.MulticastTtl = 10
udp:Open()
udp:Send( "224.0.23.175", 1234, "THIS IS A TEST" )
Because of the nature of UDP/IP, there may only be one script listening to a port on a given IP address. But another script may use that same port on a different IP address (NIC). The expected behavior of UDP-enabled remote devices is to send any responses back to the originating UDP port. The port you specify in the Send()
method is not necessarily the one you assign with the Open()
method (although they frequently match). Assuming you had many identical devices to control (via the same or separate scripts) that all used the same UDP port number for their remote interfaces, you could have many scripts, each controlling another device on the same remote UDP port. However, on the Q-SYS end, if you expect to also handle UDP responses, you need to be careful to choose unique UDP ports for the Open()
method to ensure incoming packets go to the correct script.
Unfortunately, some remote interfaces always send UDP responses to the same UDP port, regardless of the originating port on the opposite end (Q-SYS in this case). In those rare cases, you have no alternative but to write a single script to receive all responses from all devices and then farm them out to other scripts for final processing, once a determination has been made where the packet originated. This determination is typically done by parsing some type of ID from the received packet. At this point this receiver script would have to send the data to a script associated with the specific instance of remote product.
Note: One exception to this is when receiving multicast UDP packets. Those are sent to the same port on every NIC on a Layer 2 network, unless using IGMP Snooping or similar multicast filtering scheme. The above Multicast Receive example allows you to see Q-SYS Discovery Protocol (QDP) packets on your network.
If you open a UdpSocket component and assign an IP of the host interface and then use that connection to receive multicast traffic through it, it will work in Emulate Mode, but does not work when the same code is pushed to a Core until you bind the UdpSocket to the multicast group and join the multicast group.
Running on a Core (Linux)
- For traffic on a specific multicast address, the receiving socket needs to bind to the multicast group and port.
- Can also bind the wildcard IP address (INADDR_ANY - pass nil to
Open()
call) for receiving data from multiple multicast addresses. - Must also join the multicast group
JoinMulticast()
.
Running Emulate mode (Windows)
- Receiving socket needs to bind to the local interface IP and port.
- Can also bind the wildcard IP address (INADDR_ANY - pass nil to
Open()
call) for receiving data from multiple multicast addresses. - Must also join the multicast group
JoinMulticast()
.