Repeated master.getValue() calls were opening and closing the Modbus TCP socket for each read because the TCP master was created with keepalive=false. Create the master with keepalive=true to retain the connection across the reading sequence.
Identify the socket-close condition
The controller at 192.168.2.101 operates as the Modbus TCP server, while the computer at 192.168.2.69 runs the client master. A packet capture showed the connection closing after each getValue() call, disrupting an intended 500 ms polling cycle.
| Master setting | Observed connection behavior | Application impact |
|---|---|---|
keepalive=false |
Open and close the socket for every read | Repeated connection cycling during polling |
keepalive=true |
Keep the socket open across the readings and close it after the reading sequence | Reuse one connection for the batch |
Configure the Modbus4J TCP master
Pass true as the keepalive argument when creating the TCP master. Keep the same master instance for all reads in the sequence.
ModbusMaster master = modbusFactory.createTcpMaster(ipParameters, true);
NumericLocator el = new NumericLocator(
255,
RegisterRange.HOLDING_REGISTER,
0,
DataType.TWO_BYTE_INT_UNSIGNED
);
NumericLocator fjk = new NumericLocator(
255,
RegisterRange.HOLDING_REGISTER,
1,
DataType.TWO_BYTE_INT_UNSIGNED
);
for (int i = 0; i < 1113; i++) {
try {
System.out.println("el: " + master.getValue(el));
System.out.println("fjk: " + master.getValue(fjk));
} catch (Exception e) {
e.printStackTrace();
}
}
Apply and verify the correction
- Create the master once with
keepalive=truebefore entering the read loop. - Use that master instance for both holding-register reads throughout the loop.
- Capture traffic between
192.168.2.69and192.168.2.101. Confirm that the socket no longer closes between consecutivegetValue()calls and that the application still receives both register values.
Recognize the documented limits
The available evidence establishes the Boolean constructor setting and its observed effect, but it does not define an idle timeout, retry policy, parameterized keepalive interval, or the exact API call used to terminate the master after polling. Do not assume that additional keepalive timing parameters exist without checking the Modbus4J version-specific API or official documentation available with the library distribution.
FAQ
Why does Modbus4J close the TCP socket after every getValue call?
The observed cause was creating the TCP master with keepalive=false. In that configuration, each server read opened and then closed the socket.
How do I keep a Modbus4J TCP connection open for multiple reads?
Create the master with modbusFactory.createTcpMaster(ipParameters, true) and reuse that master instance across the complete reading sequence.
Can I configure the Modbus4J keepalive timeout or interval?
The evidence only identifies the Boolean keepalive constructor argument. It does not provide a supported timeout or interval parameter, so verify those capabilities against the documentation for the exact library version.