UdpSocket

The following commands can be used to send and receive data over a UDP Socket connection.

NOTE: 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 (that will remain nameless) 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, joyous 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. Thankfully, this is a rare circumstance, but one which has caused many programmers countless hours of frustration.

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 Multicast Receive example below allows you to see Q-SYS Discovery Protocol (QDP) packets on your network.

Callbacks (new in 5.3)

Beginning in Q-SYS Designer 5.3, 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.

Reference Tables

UdpSocket Properties

Name

Notes

Description

EventHandler

Signature of function is 'function(socket, data)'

 

data is a table consisting of the following:

  • Address - string
  • Port - integer
  • Data - data payload

Function to call when UDP packet is received.

Methods
Names Arguments Description

.New

None

Creates a UDP Socket instance.

:Open

( ip, port )

Opens the UDP 'listener.' Optionally bind to local IP and Port.

:Close

None

Closes the UDP socket

:Send

( ip_address, port, data )

Sends data to ip_address:port.

:JoinMulticast

( address, <ip>)

Joins a specific multicast 'address', optionally binding to a local 'ip'.

UdpSocket Data Callback

Name

Function Signature

Description

.Data

function( udpTable, data )'

data is a table consisting of the following:

  • Address - string
  • Port - integer
  • Data - data payload

Assign a function which is called when data is received (see Example 3 below)

New( )

Purpose:    Static class method. Creates a new instance of the UdpSocket class.

Return Value:   UdpSocket object

Open( <IP>, <Port> )

Purpose:     Opens the UDP socket. Optionally bind to a local IP and Port (either or both).

Parameter: IP

Type: string

Definition: Optional; The local IP address that the connection should use. If not specified, UDP would be sent from all IP addresses. Makes no difference in receiving.

Port

Type: integer, 0 - 65535

Definition: Optional; The local Port that the connection should use. If not specified, the port is selected by the system.

Close( )

Purpose:     Closes an open UDP socket on a specified port.

Send( IP_Address, Port, Data )

Purpose:     Sends data to IP Address and port.

Parameter: IP_Address

Type: string

Definition: IP Address to send to.

Port

Type: integer, 0 - 65535

Definition: Port to send to.

Data

Type: string, up to 65535 bytes

Definition: Binary data, represented in Lua as a string.

JoinMulticast( Address, <Local_IP>)

Purpose:    Joins the multicast address, optionally binding to local IP. Default is to receive multicast from all NICs.

Parameter: Address

Type: string

Definition: Multicast IP Address to receive packets from.

<Local_IP>

Type: string

Definition: Local IP address to bind to. Otherwise any matching multicast packets from any port are received.

 

Example 1: Open connection, printout Multicast UDP packets received.

-- 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

Example 2: Send a UDP message

local udp = UdpSocket.New()

 

udp:Open()

udp:Send(

"224.0.23.175",

2467,

"<QDP><query_ref>device.ioframe.*</query_ref></QDP>" )

Example 3: Using the UdpSockets Callback method.

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