stepfunc / rodbus

Rust implementation of Modbus with idiomatic bindings for C, C++, .NET, and Java
https://stepfunc.io/products/libraries/modbus/
Other
80 stars 22 forks source link

Cannot connect to rodbus server #131

Closed chenchenpowin closed 4 months ago

chenchenpowin commented 4 months ago

Hi,

I have the server in Rodbus, and client in other library(sorry have to use that). When client and server are in same process (say same SpringBoot application), client can connect to server successfully: RodbusLog - Feb 17 01:34:43.756 INFO Modbus-Server-TCP{listen=0.0.0.0:502}: accepted connection from: 172.17.0.2:50384 - assigned session id: 0

However, if client and master are in different process (same machine), I'll get connection refused error. Please suggest what could be go wrong?

Thanks!

jadamcrain commented 4 months ago

Hi @chenchenpowin.

This is unlikely to be something related to the library, and more likely to be a configuration issue. I would double check the IP/port in both situations to make sure there is no difference.

I'd need more information, e.g. some sample code of how you're using the library in both situations, to help further. If your company is a customer and wants to share anything privately, please reach out to info@stepfunc.io.

Can you share which third party library you're using as the master? I assume it's Java as well since you're able to run both within a SpringBoot app?

chenchenpowin commented 4 months ago

Hi @jadamcrain ,

Thanks for replying! The other library I used for client is jlibmodbus. Here's the code I can successfully connect to rodbus server:

  `RuntimeConfig runtimeConfig = new RuntimeConfig().withNumCoreThreads(ushort(4));
    Runtime runtime = new Runtime(runtimeConfig);

    DeviceMap map = new DeviceMap();
    map.addEndpoint(ubyte(1), new ExampleWriteHandler(), db -> {
        for(int i = 0; i < 10; i++) {
            db.addCoil(ushort(i), false);
            db.addDiscreteInput(ushort(i), false);
            db.addHoldingRegister(ushort(i), ushort(1));
            db.addInputRegister(ushort(i), ushort(2));
        }
    });
    server = Server.createTcp(runtime, "0.0.0.0", ushort(502), AddressFilter.any(), ushort(100), map, DecodeLevel.nothing());

    try {
        TcpParameters tcpParameters = new TcpParameters();

        tcpParameters.setHost(InetAddress.getLocalHost());
        tcpParameters.setKeepAlive(true);
        tcpParameters.setPort(502);

        ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
        Modbus.setAutoIncrementTransactionId(true);

        try {
            master.connect();
            int[] ints = master.readHoldingRegisters(1, 1, 1);
            System.out.println(ints[0]);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    } catch (UnknownHostException e) {
        throw new RuntimeException(e);
    }`

As you can see, I need to set server host as 0.0.0.0. If I set to 127.0.0.1, this won't work, and I'll get connection refused error. If I run the client code in same docker container as server, but different process (even if I set server's host as 0.0.0.0), still connection refused error.

Let me know if any other info you need and I'm more that happy to provide. Thank you!

jadamcrain commented 4 months ago

It does seem odd that you need to use 0.0.0.0 when they are in the same container, but I don't use Docker regularly and don't know what networking gotchas there might be there.

I would recommend trying all of this without Docker, e.g. can you make two process talk to one another on your local machine. If that works, that's a clue that it probably has more to do with docker than the applications and their configurations.

chenchenpowin commented 4 months ago

I only have a m2 Mac so won't able to test from local machine. I did try to boot up an VM, and inside VM client can connect to server from a different process, so I bet there're some networking gotchas in docker container.

However, I still won't able to get client (running on my local machine) connect to server (running in VM). I'll get connection refused error. To prevent any other networking concern, I booted up a web server in VM, and I can successfully visit web server from my local machine. So I'm not sure why the Http connection works but Modbus connection is not.

jadamcrain commented 4 months ago

1) Are you sure you're listening on 0.0.0.0 and not 127.0.0.1? 2) I wonder if the port range matters? E.g., is it possible that the VM/firewall/something blocks 502 but not the HTTP port?

I'd like to add support for M1/M2 MacOS at some point. The library is compatible with it, but the issue has been having a Mac image on Github actions to build it.

chenchenpowin commented 4 months ago

Thank you @jadamcrain . I tried 0.0.0.0 and it works. I do hope one day the version for supporting M1/M2 MacOS rolls out!