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