Loading header...

Modbus TCP — Modbus over Ethernet

Modbus TCP is proof that a software protocol and its hardware transport are genuinely independent layers. Modbus RTU was designed in 1979 for RS-485 buses. Modbus TCP, standardised in 1999, takes the same register model and function codes and runs them over a TCP/IP network — no RS-485, no CRC, no silence-based framing needed.

If you understand Modbus RTU, you already understand 90% of Modbus TCP.


The Fundamental Difference

flowchart TD classDef sw fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef trans fill:#dcfce7,stroke:#16a34a,color:#14532d classDef phys fill:#fee2e2,stroke:#dc2626,color:#7f1d1d subgraph RTU["Modbus RTU"] R1["Modbus (function codes, registers)\nSoftware protocol"]:::sw R2["UART (start/stop bits, byte framing)\nTransport"]:::trans R3["RS-485 (differential voltage, cable)\nPhysical"]:::phys R1 --> R2 --> R3 end subgraph TCP["Modbus TCP"] T1["Modbus (same function codes, same registers)\nSoftware protocol"]:::sw T2["TCP (connection, ordering, error recovery)\nTransport"]:::trans T3["Ethernet / WiFi (frames, MAC, radio)\nPhysical"]:::phys T1 --> T2 --> T3 end

The Modbus part is identical. Only the transport changes. This is the power of layered architecture — you can swap the lower layers without changing what the application sees.


The MBAP Header — What Replaces the CRC and Address

In Modbus RTU, the frame starts with a slave address and ends with a CRC. In Modbus TCP, those are replaced by the MBAP header (Modbus Application Protocol header):

Modbus RTU frame:
┌──────────┬──────────┬──────────────────┬────────┐
│  Slave   │ Function │      Data        │  CRC   │
│ Address  │   Code   │                  │ 2 byte │
│  1 byte  │  1 byte  │  0–252 bytes     │        │
└──────────┴──────────┴──────────────────┴────────┘

Modbus TCP frame:
┌──────────────┬─────────────┬──────────┬─────────┬──────────┬──────────────────┐
│ Transaction  │  Protocol   │  Length  │ Unit ID │ Function │      Data        │
│     ID       │     ID      │          │         │   Code   │                  │
│   2 bytes    │   2 bytes   │  2 bytes │  1 byte │  1 byte  │  0–252 bytes     │
└──────────────┴─────────────┴──────────┴─────────┴──────────┴──────────────────┘
Field Size Value Purpose
Transaction ID 2 bytes Client-chosen Match request to response (allows pipelining)
Protocol ID 2 bytes Always 00 00 Reserved for Modbus = 0
Length 2 bytes Byte count following Tells receiver how many more bytes to read
Unit ID 1 byte 1–247 or 255 Slave address (used when a gateway bridges to RS-485)
Function Code 1 byte Same as RTU 03, 06, 16… identical
Data Variable Same as RTU Register addresses, values — identical

No CRC — TCP itself handles error checking and retransmission. If bits flip in transit, TCP detects it and retransmits automatically.


Modbus TCP Connection — Port 502

Modbus TCP uses TCP port 502. The client (master) opens a TCP connection to the server (slave) and keeps it open for multiple requests. This is different from RTU where there is no connection concept — just a shared bus.

sequenceDiagram participant C as Modbus TCP Client (SCADA) participant S as Modbus TCP Server (Power Meter) C->>S: TCP SYN (connect to port 502) S->>C: TCP SYN-ACK C->>S: TCP ACK (connection established) C->>S: Request: TxID=0001, FC=03, Unit=01, Reg=0000, Count=2 S->>C: Response: TxID=0001, FC=03, Data=[023A][01F4] C->>S: Request: TxID=0002, FC=03, Unit=01, Reg=0002, Count=1 S->>C: Response: TxID=0002, FC=03, Data=[0064] Note over C,S: Connection stays open — no need to reconnect per request C->>S: TCP FIN (close when done)

Multiple Masters — A Key Advantage Over RTU

Modbus RTU on RS-485 allows only one master. Modbus TCP has no such restriction — multiple clients can connect to the same server simultaneously. Each client has its own TCP connection:

flowchart LR classDef client fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef server fill:#dcfce7,stroke:#16a34a,color:#14532d classDef net fill:#fef9c3,stroke:#ca8a04,color:#713f12 SCADA["SCADA System\n(Master 1)"]:::client HMI["HMI Panel\n(Master 2)"]:::client LOG["Data Logger\n(Master 3)"]:::client ETH["Ethernet Switch"]:::net PM["Power Meter\nModbus TCP Server\nPort 502"]:::server INV["Solar Inverter\nModbus TCP Server\nPort 502"]:::server SCADA --> ETH HMI --> ETH LOG --> ETH ETH --> PM ETH --> INV

All three masters can query any server independently and simultaneously.


Gateways — Bridging RTU and TCP

The vast majority of industrial field devices (sensors, meters, drives) still use Modbus RTU over RS-485. But control systems increasingly live on Ethernet networks. A Modbus gateway bridges the two worlds:

flowchart LR classDef tcp fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef gw fill:#fef9c3,stroke:#ca8a04,color:#713f12 classDef rtu fill:#dcfce7,stroke:#16a34a,color:#14532d SCADA["SCADA / PLC\nModbus TCP Client\n(Ethernet)"]:::tcp GW["Modbus Gateway\nReceives TCP requests\nConverts to RTU frames\nPolls RS-485 bus\nReturns response via TCP"]:::gw S1["Slave 01\nPower Meter"]:::rtu S2["Slave 02\nTemp Controller"]:::rtu S3["Slave 03\nVFD"]:::rtu SCADA <-->|"Ethernet\nModbus TCP"| GW GW <-->|"RS-485\nModbus RTU"| S1 GW <-->|"RS-485\nModbus RTU"| S2 GW <-->|"RS-485\nModbus RTU"| S3

From the SCADA system's perspective, all three field devices look like Modbus TCP servers. The gateway handles the translation transparently.


RTU vs TCP — Head to Head

Modbus RTU Modbus TCP
Physical layer RS-485 (or RS-232) Ethernet, WiFi
Transport UART (start/stop bits) TCP/IP
Port N/A (bus address) TCP 502
Error checking CRC (in frame) TCP checksum (automatic)
Frame delimiter 3.5 character silence Length field in header
Masters per bus 1 only Multiple (one TCP connection each)
Max devices 247 slaves Unlimited (TCP network limit)
Latency Very low (~5–10 ms) Higher (TCP handshake, network hops)
Distance Up to 1200 m (RS-485) Unlimited (routable over internet)
Security None TLS possible (Modbus TCP over TLS)
Cost Cheap (RS-485 transceivers) Higher (Ethernet hardware)
Best for Legacy field devices, meters, drives Modern SCADA, cloud integration, multi-master

The Register Model is Identical

This is worth repeating: the registers, coils, function codes, and data values are identical between RTU and TCP. A power meter that exports:

  • Voltage in register 0000
  • Current in register 0001
  • Power in register 0002

...uses those same register numbers whether you connect via RS-485 or Ethernet. The device's register map does not change based on transport.


Modbus in the Protocol Stack

Now you can see where Modbus sits in the full communication stack:

flowchart TD classDef app fill:#dbeafe,stroke:#2563eb,color:#1e3a5f classDef tran fill:#dcfce7,stroke:#16a34a,color:#14532d classDef link fill:#ffedd5,stroke:#ea580c,color:#9a3412 classDef phys fill:#fee2e2,stroke:#dc2626,color:#7f1d1d subgraph TCP_STACK["Modbus TCP Stack"] A1["Modbus\n(Application — function codes, registers)"]:::app A2["TCP\n(Transport — reliable delivery)"]:::tran A3["IP\n(Network — addressing, routing)"]:::tran A4["Ethernet / WiFi\n(Data Link + Physical)"]:::phys A1 --> A2 --> A3 --> A4 end subgraph RTU_STACK["Modbus RTU Stack"] B1["Modbus\n(Application — same function codes, same registers)"]:::app B2["UART framing\n(start bit, 8 data bits, stop bit, CRC)"]:::link B3["RS-485\n(Differential physical layer)"]:::phys B1 --> B2 --> B3 end

Key Takeaway

Modbus TCP proves that a software protocol and a hardware transport are entirely independent layers. The Modbus registers, function codes, and data model invented in 1979 for RS-485 buses work identically over modern Ethernet networks — only the wrapper changes.

When you see a system with both RS-485 field devices and an Ethernet-connected SCADA server, a Modbus gateway bridges the two automatically. Understanding the layering is what lets you configure, troubleshoot, and extend such systems confidently.