Detection of disconnected server when using tcpclient() and write()

14 views (last 30 days)
I am using the tcpclient() function to establish a connection to a server I built and I would like to be able to detect when the server disconnects. My current understanding is that the way to do that is to attempt a write and if the write fails, the connection can be considered as disconnected.
% I start the server before the first matlab command
t= tcpclient("192.168.10.188", 65434); %connects to server
msg = uint8([1,2,3]); % basic message with 3 bytes
write(t,msg); % sends message to server. Server receives the data.
write(t,msg); % sends message to server. Server receives the data.
write(t,msg); % sends message to server. Server receives the data.
write(t,msg); % sends message to server. Server receives the data.
The above code works fine as expected.
Next, I run the same code, but I disconnect the server after the connection is established but before the write is sent.
% I start the server before the first matlab command
t= tcpclient("192.168.10.188", 65434);
% I disconnect the server before attempting the first write
msg = uint8([1,2,3]); % basic message with 3 bytes
write(t,msg); % sends message to disconnected server. No error raised.
write(t,msg); % sends message to disconnected server. "Error using asyncio.MessageHandler/onError" is shown in command window
write(t,msg); % sends message to disconnected server. "An established connection was terminated. Please create a new TCPCLIENT." is shown in command window
write(t,msg); % sends message to disconnected server. "Invalid or deleted object." is shown in command window.
I can handle the last 2 errors using a try/catch, but I am not able to handle the "Error using asyncio.MessageHandler/onError" error with a try/catch.
I think this is because the error is raised asynchronously. I would like to be able to catch this error to avoid error messages in the final application.
According to the tcpclient page, there is a callback property called ErrorOccurredFcn that seems to be built to handle that.
However, even with the following code, I still get the same "Error using asyncio.MessageHandler/onError" error and my error handler function is not executed.
function error_handler()
disp("Asynchronous error handled"); % never executed
end
% I start the server before the first matlab command
t= tcpclient("192.168.10.188", 65434);
t.ErrorOccurredFcn = @error_handler;
% I disconnect the server before attempting the first write
msg = uint8([1,2,3]); % basic message with 3 bytes
write(t,msg); % sends message to disconnected server. No error raised.
write(t,msg); % sends message to disconnected server. "Error using asyncio.MessageHandler/onError" is shown in command window
So, I still get an error in the command window after using the ErrorOccurredFcn callback property.
The read() command does not seem to raise an exception whenever the server is disconnected.
So, what is the proper way to detect if the server is disconnected without getting an error in the command window?
  1 Comment
Walter Roberson
Walter Roberson on 14 Nov 2020
Unfortunately it is difficult to tell. The internal client is created by matlabshared.network.internal.TCPClient which is toolbox/shared/networklib/+matlabshared/+network/+internal/TCPClient.p and the message handler is toolbox/shared/asynciolib/+asyncio/MessageHandler.m which just does error() or throwAsCaller() and there is no user-visible connection between the two. I think we can assume that TCPClient.p creates a class structure that uses MessageHandler but how the two get connected is unclear.

Sign in to comment.

Answers (1)

Abhiram
Abhiram on 23 Jan 2025
Edited: Abhiram on 23 Jan 2025
Hi Bruno,
I understand that you are using the MATLAB “tcpclient” function to establish a connection to a server but want to detect if the server is disconnected without getting an error.
For MATLAB versions R2021b and later, a workaround can be implemented by following the given steps:
  1. Run MATLAB as administrator using “Run as administrator”.
  2. Edit “<matlabroot>\toolbox\matlab\networklib\tcpclient.m” file.
  3. Add the line “setProperty(obj.TCPCustomClient, "WriteAsync", false);” after the line “connect(obj.TCPCustomClient);”.
  4. Use “try-catch” to handle the error thrown by “asyncio.MessageHandler/onError”.
An example code snippet is given below for better understanding on how to work around the issue:
port_num = 8080;
server = tcpserver(port_num);
t= tcpclient("localhost", port_num);
msg = uint8([1,2,3]); % basic message with 3 bytes
% Confirm that tcpserver and tcpclient work as expected when used normally
write(t,msg);
disp("Now reading data received by server:");
read(server,3)
% Disconnect the server before attempting to write
clear server;
try
write(t,msg);
catch e
disp("Caught the error!");
end
Note that this workaround changes the behaviour of the MATLAB “write” function to be blocking, which means MATLAB code execution will pause until the write operation completes, which may take a long time if the connection has failed. This workaround may not be appropriate when we may need to perform a large number of “write” operations and relies on the function not blocking, that is when the function calls must execute asynchronously.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!