Skip to content

TcpSocket

Overview

TcpSocket API allows communication to other devices via TCP. The TcpSocket API only works using the control network.

TCPSocket.

Return Type Comment
TcpSocket.New() TCPSocket object Used to create a new TCPSocket object.

TcpSocket.New()

New() creates a TcpSocket object as a global table.

MyTcp = TcpSocket.New()
Up to 8 TcpSocket objects can be simultaneously requested with separate calls. When a socket is closed (see below), it is available for use again with another New call.

TcpSocketName

The following methods and properties are available for a TcpSocket object with name “TcpSocketName”.

Return Type Comment
TcpSocketName.ID Integer The number of the socket in the script.
TcpSocketName.EventHandler(TcpSocket, event, error) Callback Called when an event has occurred with an argument of the TcpSocket table, an event from the Events Table and any error string.
TcpSocketName.ReadTimeout Number The time in seconds to wait for a read to complete before the socket times out. 0 disables the timeout.
TcpSocketName.WriteTimeout Number The time in seconds to wait for a write to complete before the socket times out. 0 disables the timeout.
TcpSocketName.ReconnectTimeout Number The time in seconds to wait before reconnecting if the socket disconnects externally.
TcpSocketName.IsConnected Boolean Indicates if the socket is currently connected.
TcpSocketName.BufferLength Integer The count of bytes received and waiting to be read.
TcpSocketName:Connect(ip, port) Method Connects the socket to an IP address.
TcpSocketName:Disconnect() Method Disconnects a connected socket
TcpSocketName:Write(data) Method Writes a table of data to a connected socket.
TcpSocketName:Read(length) Method Reads an integer count of bytes into a returned table from the connected socket.
TcpSocketName:ReadLine(EOL, [delimiter]) Method Reads into a returned table until the specified EOL enumeration case is encountered. If it is a custom delimiter, then it is specified as a string.
TcpSocketName:Search(pattern, [start]) Method Searches the unread data in the socket for a string starting at an optional 1-based start index. Returns the 1-based index but not the data.
TcpSocketName.Connected(TcpSocket) Callback Called when a socket connects with an argument of the TcpSocket table.
TcpSocketName.Reconnect(TcpSocket) Callback Called when a socket is attempting to reconnect with an argument of the TcpSocket table.
TcpSocketName.Data(TcpSocket, data) Callback Called when unread data is available with an argument of the TcpSocket table and the data table.
TcpSocketName.Closed(TcpSocket) Callback Called when a socket is closed with an argument of the TcpSocket table.
TcpSocketName.Error(TcpSocket, error) Callback Called when there is an error with an argument of the TcpScocket table and the error string.
TcpSocketName.Timeout(TcpSocket, error) Callback Called when there is read or write timeout with an argument of the TcpScocket table and the error string.

TcpSocketName.ID

The 1-8 number of the socket in the script.

print(MyTCPSocket.ID)                     >> 1
Up to 8 TcpSocket objects can be simultaneously requested with separate calls. When a socket is closed (see below), it is available for use again with another New call.

TcpSocketName.EventHandler(TcpSocket, event, error)

Assign the callback function for the TcpSocket that will be called whenever an event occurs with an argument of the TcpSocket table, an event from the Events Table and any error string.

This can be done in two ways. With a dedicated function:

function TcpHandler (sock, evt, err)
      --handle the event
end

sock.EventHandler = TcpHandler
Alternately, you can use an anonymous function:
sock.EventHandler = function(sock, evt, err)
      --handle the event
end

Usually, you will be handling the multiple possible event types with if-elseif-else statements. To help with readability in your comparisons, there is a table of “TcpSocket.Events.” enumerations.

Enumeration Value Functionality
“Connected” 1 The TcpSocket connected.
“Reconnect” 2 The TcpSocket is attempting to reconnect.
“Data” 3 The TcpSocket has data available.
“Closed” 4 The TcpSocket has closed.
“Error” 5 The TcpSocket has errored.
“Timeout” 6 The TcpSocket has timed out.

See the Example1 to see how this is used.

TcpSocketName.ReadTimeout

Set the ReadTimeout for the TCP socket. This configures the time in seconds to wait for a read to complete before the socket times out. The default is 0, which disables the read timeout so the socket will wait indefinitely.

mySock.ReadTimeout = 5
When a read timeout occurs, the Timeout callback is called (or the “Timeout” case in the general EventHandler). Set to 0 to disable the timeout.

TcpSocketName.WriteTimeout

Set the WriteTimeout for the TCP socket. This configures the time in seconds to wait for a write to complete before the socket times out. The default is 0, which disables the write timeout so the socket will wait indefinitely.

mySock.WriteTimeout = 5
When a write timeout occurs, the Timeout callback is called (or the “Timeout” case in the general EventHandler). Set to 0 to disable the timeout.

TcpSocketName.ReconnectTimeout

Set the ReconnectTimeout for the TCP socket, overriding the default value of 5 seconds. This configures the time in seconds to wait before attempting to reconnect if the socket disconnects externally. Set to 0 for no wait.

mySock.ReconnectTimeout = 1
Normally the default is acceptable, but you may need to adjust this if you know the device you are connecting to requires a longer period before reconnect.

Additionally, it is good practice to manually monitor connection status and have a reconnect path in your code.

TcpSocketName.IsConnected

Indicates if the socket is currently connected.

print(mySock.IsConnected)           >> True
This is used to test connection state and take appropriate action.

TcpSocketName.BufferLength

The count of bytes received and waiting to be read.

print(mySock.BufferLength)          >> 8

TcpSocketName:Connect(ip, port)

Called to connect the socket to an IP address and port (0-65535). This must be an IP address; hostnames are not supported.

sock:Connect("169.254.179.214", port)
Information from the Device table can be used to ensure the correct IP address is used.
currentDeviceIP = Device.RemoteUnit.DanteIP
sock:Connect(currentDeviceIP, port)

TcpSocketName:Disconnect()

Call to disconnects a connected socket.

sock:Disconnect()                   -- socket is disconnected

TcpSocketName:Write(data)

Call to write a table of data to a connected socket.

sock:Write('V\x0d')                 -- Data is written and sent

TcpSocketName:Read(length)

Call to read an integer “length” of bytes into a returned table from the connected socket buffer.

rx = sock:Read(10000)
The read bytes are removed from the buffer.

TcpSocketName:ReadLine(EOL, [delimiter])

Call to reads into a returned table until the specified EOL enumeration case is encountered.

rxLine = sock:ReadLine(1)     --Read until any combination of linefeeds and returns are reached

The “TcpSocket.EOL.” enumerations are listed in the table below.

Enumeration Value Functionality
Any 1 Search for any combination of linefeeds and returns.
CrLf 2 Search for a return or linefeed and return.
CrLfStrict 3 Search for a linefeed and a return.
Lf 4 Search for a linefeed.
Null 5 Search for an ASCII zero terminator.
Custom 6 Search for a custom string.
rxLine = sock:ReadLine(TcpSocket.EOL.Any) --Read until any combination of linefeeds and returns are reached

If “Custom” is used for the EOL enumeration, then it is specified as a string with the optional second delimiter argument.

rxLine = sock:Readline(6, "TheEnd") --Read until "TheEnd" is reached

TcpSocketName:Search(pattern, [start])

Searches the unread data in the socket for a string starting at an optional 1-based start index. Returns the 1-based index but not the data.

TcpSocketName:Search("ImportantMessage", 1)                 >> 16
TcpSocketName:Search("AnotherMessage", 17)                  >> nil

Search looks for the exact string passed in. There is no interpretation of specific characters in the search string (e.g. * or ?) and Lua pattern matching is not supported.

Search can be used to improve efficiency in situations where you are looking for looking for a particular response. This can be useful for a protocol that put out a lot of data and you only care about one thing. Instead of reading each line and parsing the data looking for a particular string, the script can search for it, and if it doesn’t exist, throw all of the received data away with a single Read() command.

TcpSocketName.Connected(TcpSocket)

Define a callback function that will be called when a socket connects with an argument of the TcpSocket table.

This can be done in two ways. With a dedicated function:

function ConnectedHandler (TcpSocket)

      --handle the new Connection
end

sock.Connected = ConnectedHandler

Alternately, you can use an anonymous function:

sock.Connected = function(TcpSocket)
      --handle the new Connection
end
This can be used instead of the general EventHandler callback. See Example 2 below.

TcpSocketName.Reconnect(TcpSocket)

Define a callback function that will be called when a socket is attempting to reconnect with an argument of the TcpSocket table.

This can be done in two ways. With a dedicated function:

function ReconnectHandler (TcpSocket)
      --handle the Reconnection attempt
end

sock.Reconnect = ReconnectHandler

Alternately, you can use an anonymous function:

sock.Reconnect = function(TcpSocket)
      --handle the Reconnection attempt
end

This can be used instead of the general EventHandler callback. See Example 2 below.

TcpSocketName.Data(TcpSocket, data)

Define a callback function that will be called when unread data is available with an argument of the TcpSocket table and the data table.

This can be done in two ways. With a dedicated function:

function DataHandler (TcpSocket, data)
      --handle the data
end

sock.Data = DataHandler

Alternately, you can use an anonymous function:

sock.Data = function(TcpSocket, data)
      --handle the data
end

The “data” can be read with the Read or ReadLine functions.

This can be used instead of the general EventHandler callback. See Example 2 below.

TcpSocketName.Closed(TcpSocket)

Define a callback function that will be called when a socket is closed with an argument of the TcpSocket table.

This can be done in two ways. With a dedicated function:

function ClosedHandler (TcpSocket)
      --handle the socket closing
end

sock.Closed = ClosedHandler

Alternately, you can use an anonymous function:

sock.Closed = function(TcpSocket)
      --handle the socket closing
end

This can be used instead of the general EventHandler callback. See Example 2 below.

TcpSocketName.Error(TcpSocket, error)

Define a callback function that will be called when there is an error with an argument of the TcpScocket table and the error string.

This can be done in two ways. With a dedicated function:

function ErrorHandler (TcpSocket, error)
      --handle the error
end

sock.Error = ErrorHandler
Alternately, you can use an anonymous function:
sock.Error = function(TcpSocket, error)
      --handle the error
end

This can be used instead of the general EventHandler callback. See Example 2 below.

TcpSocketName.Timeout(TcpSocket, error)

Define a callback function that will be called when there is read or write timeout with an argument of the TcpScocket table and the error string.

This can be done in two ways. With a dedicated function:

function TimeoutHandler (TcpSocket, error)
      --handle the Timeout
end

sock.Timeout = TimeoutHandler

Alternately, you can use an anonymous function:

sock.Timeout = function(TcpSocket, error)
      --handle the Timeout
end

This can be used instead of the general EventHandler callback. See Example 2 below.

Usage Examples

The following examples illustrate how these can be used:

Example 1 – Putting it all together

This example shows how TcpSocket is typically used

sock = TcpSocket.New()
sock.ReadTimeout = 0
sock.WriteTimeout = 0
sock.ReconnectTimeout = 0

sock.EventHandler = function(sock, evt, err)
      if evt == TcpSocket.Events.Connected then
            --handle the new Connection
            print("socket connected\r")
      elseif evt == TcpSocket.Events.Reconnect then
            --handle the Reconnection attempt
            print("socket reconnecting...\r")
      elseif evt == TcpSocket.Events.Data then
            --handle the data
            rxLine = sock:Read(10000)
            if (nil ~= rxLine) then
                  print("Got:\r" .. rxLine)
            end
      elseif evt == TcpSocket.Events.Closed then
            --handle the socket closing
            print("socket closed by remote\r")
      elseif evt == TcpSocket.Events.Error then
            --handle the error
            print(string.format("Error: '%s'\r", err))
      elseif evt == TcpSocket.Events.Timeout then
            --handle the Timeout
            print("socket closed due to timeout\r")
      else
            print("unknown socket event\r")
      end
end

sock:Connect(remoteControlIp, remoteControlPort)
The Events enumeration table described above is used to compare the received “evt” and perform the appropriate action. You should generally always handle all 6 possible event types in the enumeration table as shown.

Example 2 - Discrete Handlers

Instead of handling all the events with a single handler, you can alternately use a separate handler per event type. This may be preferable as it tends to be easier to read since there isn’t a large section of if-ifelse needed.

sock = TcpSocket.New()
sock.ReadTimeout = 0
sock.WriteTimeout = 0
sock.ReconnectTimeout = 0

sock.Connected = function(TcpSocket)
      --handle the new Connection
      print("socket connected\r")
end

sock.Reconnect = function(TcpSocket)
      --handle the Reconnection attempt
      print("socket reconnecting...\r")
end

sock.Data = function(TcpSocket, data)
      --handle the data
      rxLine = sock:Read(10000)

      if (nil ~= rxLine) then
            print("Got:\r" .. rxLine)
      end
end

sock.Closed = function(TcpSocket)
      --handle the socket closing
      print("socket closed by remote\r")
end

sock.Error = function(TcpSocket, error)
      --handle the error
      print(string.format("Error: '%s'\r", error))
end

sock.Timeout = function(TcpSocket, error)
      --handle the Timeout
      print("socket closed due to timeout\r")
end

sock:Connect(remoteControlIp, remoteControlPort)