Skip to main content

TCP server

Each TCP server processes requests for one or more unit IDs from multiple external clients.

The DeviceMap class (ServerHandlerMap in Rust) associates each unit ID with the data and write handling you provide to clients. The server doesn't reply to a request for a unit ID that isn't in the map.

Creating a server​

First build a DeviceMap for each unit ID the server must support. Then use the create_tcp static method of the Server class (spawn_tcp_server_task in Rust). The server starts listening immediately, and creation fails if it can't bind the port, for example when another process already uses it.

You also choose the local address to listen on, such as:

  • 127.0.0.1 for localhost only
  • 0.0.0.0 for all adapters
  • The IP address of a particular adapter

The other arguments are the AddressFilter, the maximum number of sessions and the decode level; the API docs describe each one. The AddressFilter limits which client IP addresses may connect; AddressFilter.any() allows all of them, and the filter also accepts IPv4 wildcards such as 192.168.0.*.

When a new connection would exceed the maximum number of sessions, the server closes the oldest session to make room.

let handler = SimpleHandler::new(POINT_COUNT).wrap();

// map unit ids to a handler for processing requests
let map = ServerHandlerMap::single(UnitId::new(UNIT_ID), handler.clone());

let server = rodbus::server::spawn_tcp_server_task(
MAX_SESSIONS,
endpoint,
map,
AddressFilter::Any,
DecodeLevel::new(
AppDecodeLevel::DataHeaders,
FrameDecodeLevel::Nothing,
PhysDecodeLevel::Nothing,
),
)
.await?;

In Rust, the wrap() method of RequestHandler moves your handler into the Arc<Mutex> that the ServerHandlerMap holds.