Hi @serhmarch
Thank you for sharing your library!
I think I might found an issue in the TCP client in blocking mode.
Environment
- ModbusLib Version: v0.4.9
- Compiler: aarch64-none-linux-gnu, 14.2rel1
- Platform: aarch64, Linux 64 bit, kernel 6.12.63-v8-16k
Description
There seems to be an issue on Linux with the Modbus TCP client in blocking mode.
When the connection is lost while awaiting a response from the server, ModbusClientPort::readHoldingRegisters() returns Status_Processing.
This results in blocked communication during further requests, where all requests return Status_Processing after the configured timeout. This situation remains until the kernel destroys the socket itself. (about 15 minutes)
In non-blocking mode this is not an issue. No matter at what point the connection is lost, the lib returns an error and further requests are successful again.
The issue can be reproduced by using clumsy, setting a lag/delay of 1000 ms, and then click RST next packet when a request was sent, but before the response is received.
Used config:
Modbus::TcpSettings settings;
settings.host = "<server ip address>";
settings.port = 502;
settings.timeout = 5000;
client_ = Modbus::createClientPort(Modbus::TCP, &settings, true)
uint16_t data = 0;
status = client_.readHoldingRegisters(1, 12, 1, &data);
if (Modbus::StatusIsProcessing(status)) {
// I think this should never be reached, but it does.
// If further requests are made, they all time out and arrive here
}
Root cause
I think the issue is in ModbusTcpPort::read() in ModbusTcpPort_unix.cpp:
In case STATE_WAIT_FOR_READ_ALL:, the last else block:
else
{
int e = errno;
if (e != EWOULDBLOCK)
{
close();
....
}
}
If errno is EWOULDBLOCK (== EAGAIN), the socket is not closed and Status_Processing is returned.
This in turn slips through the state machine StatusCode ModbusClientPort::process() in ModbusClientPort.cpp:
Where case STATE_READ: does
r = d->port->read();
if (StatusIsProcessing(r))
return r;
Hi @serhmarch
Thank you for sharing your library!
I think I might found an issue in the TCP client in blocking mode.
Environment
Description
There seems to be an issue on Linux with the Modbus TCP client in blocking mode.
When the connection is lost while awaiting a response from the server,
ModbusClientPort::readHoldingRegisters()returnsStatus_Processing.This results in blocked communication during further requests, where all requests return
Status_Processingafter the configured timeout. This situation remains until the kernel destroys the socket itself. (about 15 minutes)In non-blocking mode this is not an issue. No matter at what point the connection is lost, the lib returns an error and further requests are successful again.
The issue can be reproduced by using clumsy, setting a lag/delay of 1000 ms, and then click
RST next packetwhen a request was sent, but before the response is received.Used config:
Root cause
I think the issue is in
ModbusTcpPort::read()inModbusTcpPort_unix.cpp:In
case STATE_WAIT_FOR_READ_ALL:, the lastelseblock:If
errnoisEWOULDBLOCK(==EAGAIN), the socket is not closed andStatus_Processingis returned.This in turn slips through the state machine
StatusCode ModbusClientPort::process()inModbusClientPort.cpp:Where
case STATE_READ:does