tokio_modbus/client/
tcp.rs

1// SPDX-FileCopyrightText: Copyright (c) 2017-2025 slowtec GmbH <post@slowtec.de>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! TCP client connections
5
6use std::{fmt, io, net::SocketAddr};
7
8use tokio::{
9    io::{AsyncRead, AsyncWrite},
10    net::TcpStream,
11};
12
13use super::*;
14
15/// Establish a direct connection to a Modbus TCP coupler.
16pub async fn connect(socket_addr: SocketAddr) -> io::Result<Context> {
17    connect_slave(socket_addr, Slave::tcp_device()).await
18}
19
20/// Connect to a physical, broadcast, or custom Modbus device,
21/// probably through a Modbus TCP gateway that is forwarding
22/// messages to/from the corresponding slave device.
23pub async fn connect_slave(socket_addr: SocketAddr, slave: Slave) -> io::Result<Context> {
24    let transport = TcpStream::connect(socket_addr).await?;
25    let context = attach_slave(transport, slave);
26    Ok(context)
27}
28
29/// Attach a new client context to a direct transport connection.
30///
31/// The connection could either be an ordinary [`TcpStream`] or a TLS connection.
32pub fn attach<T>(transport: T) -> Context
33where
34    T: AsyncRead + AsyncWrite + Send + Unpin + fmt::Debug + 'static,
35{
36    attach_slave(transport, Slave::tcp_device())
37}
38
39/// Attach a new client context to a transport connection.
40///
41/// The connection could either be an ordinary [`TcpStream`] or a TLS connection.
42pub fn attach_slave<T>(transport: T, slave: Slave) -> Context
43where
44    T: AsyncRead + AsyncWrite + Send + Unpin + fmt::Debug + 'static,
45{
46    let client = crate::service::tcp::Client::new(transport, slave);
47    Context {
48        client: Box::new(client),
49    }
50}