Modbus TCP/IP server with multiple sockets open

510 views
Skip to first unread message

wjba...@ncsu.edu

unread,
May 25, 2017, 6:47:10 PM5/25/17
to libmodbus
Hello,

I'm using libmodbus v3.0.6 to create a Modbus server over TCP/IP. I started by basing my code off of `tests/random-test-server.c` (except  I'm using the `*_pi_*` set of functions).

I'd like to extend this to be multi-threaded to allow multiple clients  to be connected simultaneously. The thought is this:
  1. Create `ctx` and `mb_mapping` as usual.
  2. Create an infinite loop that calls `modbus_tcp_pi_listen` and `modbus_tcp_pi_accept` at the top.
  3. Whenever I get an open socket, spawn off a worker thread which:
    1. receives the socket file descriptor as data,
    2. calls `modbus_receive` and handles the message appropriately,
    3. repeats until `modbus_receive` indicates the client has closed the connection
    4. closes the socket.
The problem: I can't specify a sockfd to `modbus_receive`. It gets it from `ctx`, but that's global so the sockfd gets overwritten when a second client connects.

For those that prefer to read code, this is as close as I've gotten:

/* server_init, which sets up `ctx` and `mb_mapping`, omitted for brevity */

static void *
server_work_thread
(void *data)
{
   
int socket = (int) *((int *) data);
    uint8_t query
[MODBUS_TCP_MAX_ADU_LENGTH];
   
int rc;

   
while (TRUE)
   
{
       
/* how do i specify a socket here? */
        rc
= modbus_receive (ctx, query);
       
if (rc < 0)
       
{
           
/* connection closed by client or error */
           
break;
       
}

       
/* do stuff with the query */
   
}

    close
(socket);
   
return NULL;
}

void
server_run
()
{
   
while (TRUE)
   
{
       
int rc;
       
int socket;
        pthread_t work_thread
;
        socket
= modbus_tcp_pi_listen (ctx, 1);
        modbus_tcp_pi_accept
(ctx, &socket);
        pthread_create
(&work_thread, NULL, server_work_thread, &socket);
       
/* error handling and `pthread_join` logic omitted for brevity */
   
}
}

Does the API currently have a way of servicing multiple simultaneously open sockets?

I noticed a function called `modbus_receive_from` in `modbus.h` which takes a sockfd as an argument, but there doesn't seem to be a corresponding implementation.

Thank you,
 - Woodrow Barlow
Reply all
Reply to author
Forward
0 new messages