Modbus4J Keepalive: Configuring Persistent TCP Sockets

Daniel Price2 min read
ModbusOther ManufacturerTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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

  1. Create the master once with keepalive=true before entering the read loop.
  2. Use that master instance for both holding-register reads throughout the loop.
  3. Capture traffic between 192.168.2.69 and 192.168.2.101. Confirm that the socket no longer closes between consecutive getValue() 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.

Back to blog