Configuring Two TCP Connections on S7-315-2 PN/DP with TCON

David Krause14 min read
S7-300SiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Configuring Two TCP Connections on S7-315-2 PN/DP with TCON

A frequent integration scenario with the SIMATIC S7-315-2 PN/DP (CPU 315-2 EH14 or later, firmware V3.x) is to open two parallel TCP sockets from one PLC to a PC application — typically one channel for process data (Matlab, OPC, custom .NET service) and a second channel for diagnostics, HMI, or a redundant data path. Siemens' Open User Communication blocks (TCON, TSEND, TRCV, TDISCON) support multiple connections, but the first-time integrator almost always runs into the same symptom: the second FB300 TCON call returns STATUS = 16#7000 forever, and DONE never flips. The root cause is the same in nine out of ten cases, and it has nothing to do with the partner IP, the firewall, or the port number. This reference explains the full parameter stack, the byte-level layout of the Connection ID, and the field-proven commissioning procedure that gets both sockets up.

1. Problem Description

Symptom observed on a STEP 7 V5.5 / V5.6 project targeting an S7-315-2 PN/DP (6ES7 315-2EH14-0AB0):

  • Connection 1 (e.g. ID = W#16#0001, port 2000) — FB300 TCON returns STATUS = 16#0000, DONE = TRUE. PC receives the SYN, data flows.
  • Connection 2 (e.g. ID = W#16#0001, port 2001) — the engineer copies FB300, generates a new instance DB (DB301 for example), updates TCON_PARAM in UDT65 with the second port, but the call sits permanently at STATUS = 16#7000.
  • No entry appears in the CPU diagnostic buffer, no partner SYN is sent, the PC never sees the second socket.

Status 16#7000 in the Open User Communication blocks is the placeholder value written when the instruction has no active job. It is not a fatal error — it is a "nothing to do" return. A persistently stuck 16#7000 almost always means the call is not being triggered correctly, the instance is wrong, or two TCON calls are configured to compete for the same internal connection resource.

2. Root Cause: Duplicate Connection ID Byte

On the S7-300/400 Open User Communication stack, every connection must be uniquely identified by the local Connection ID stored in UDT65 field id (WORD). Two TCON instances with the same id collide inside the CPU's connection resource table. The CPU silently refuses to start the second call, leaves it idle, and the call keeps reading the buffer where the previous job completed — so STATUS stays at the initial 16#7000.

The fix in the original Siemens support thread was to change the Connection ID Hi byte (the high-order byte of the W#16#xxxx WORD) of the second TCON. The Lo byte is the local connection number; the Hi byte carries additional routing/connection-class information and must be different for every concurrent connection when the CPU distinguishes the sessions by the high-order identifier.

Engineering rule: Every active TCON, TSEND, TRCV, and TDISCON call on an S7-300 must reference a unique id field. The cleanest scheme is to increment the Lo byte and leave the Hi byte at zero, or to use a unique value in the Hi byte (e.g. W#16#0001 for connection 1, W#16#0101 for connection 2) — the exact scheme depends on the CPU firmware and the connection type. Whatever scheme you pick, no two TCONs may share the same 16-bit ID.

3. Connection ID Byte Layout

The id field inside UDT65 TCON_PARAM is a 16-bit WORD with the following conventional split:

Bit Range Field Meaning
Bit 0–7 (Lo byte) Local connection number Unique per active/open connection on the CPU. Range 1–16 (CPU-dependent).
Bit 8–14 Reserved / extended ID Used for connection-class flags in some firmware versions.
Bit 15 (Hi byte, MSB) Direction / passive-active flag Indicates whether the local side is the passive (server) or active (client) endpoint, or contains the high-byte of the extended ID.

For a clean dual-connection design on the S7-315-2 PN/DP, the engineer can use either of the following ID schemes:

Connection Scheme A (Lo-byte increment) Scheme B (Hi-byte split, as in the original Siemens fix)
Connection 1 — process data W#16#0001 W#16#0001
Connection 2 — diagnostics W#16#0002 W#16#0101
Connection 3 — spare W#16#0003 W#16#0201

Either scheme works as long as the 16-bit values are unique. The original Siemens thread confirmed that incrementing the Hi byte resolved the issue when the Lo byte was already used for other S7 connections (HMI, PG, OP) on the same CPU.

4. UDT65 TCON_PARAM Structure

FB300 TCON takes a single TCON_PARAM pointer (any DB of type UDT65 "TCON_PARAM"). The UDT layout is:

Offset (bytes) Field Type Sample for Connection 1 Sample for Connection 2
0 id (Block ID / connection ID) WORD W#16#0001 W#16#0101
2 connection_type BYTE B#16#11 (TCP) B#16#11 (TCP)
3 active_est (active/passive) BOOL TRUE (PLC dials out) TRUE (PLC dials out)
4 local_device_id BYTE B#16#00 B#16#00
5 local_tsap_id_len BYTE B#16#00 (auto for TCP) B#16#00
6 local_tsap_id ARRAY[1..16] OF BYTE 00 00 00 00 ... 00 00 00 00 ...
22 rem_subnet_id_len BYTE B#16#00 B#16#00
23 rem_subnet_id ARRAY[1..6] OF BYTE 00 ... 00 ...
29 rem_staddr_len BYTE B#16#04 (IPv4) B#16#04
30 rem_staddr (remote IP) ARRAY[1..16] OF BYTE 192 168 0 50 ... 192 168 0 50 ...
46 rem_tsap_id_len BYTE B#16#02 (port) B#16#02
47 rem_tsap_id (remote port) ARRAY[1..16] OF BYTE 00 7D 00 ... (port 2000 = 0x07D0) 00 7D 01 ... (port 2001 = 0x07D1)
63 next_staddr_len BYTE B#16#00 B#16#00
64 next_staddr ARRAY[1..6] OF BYTE 00 ... 00 ...

Two parameters must be unique per TCON: the id WORD and the remote port in rem_tsap_id. The remote IP can be identical for both sockets (both sockets from the same PC) — that is normal. Setting both active_est = TRUE with the same remote IP is valid; the PLC will open two independent TCP sessions distinguished by the local port auto-assigned by the CPU and the unique Connection ID.

5. Step-by-Step Configuration for Two TCP Connections

  1. Declare two instance DBs. In the S7 program, create DB100 as the instance for the first FB300 call and DB101 as the instance for the second. Generate them via the FB's "Instance DB" right-click menu so that the multi-instance layout is correct.
  2. Declare two parameter DBs of type UDT65 "TCON_PARAM". For example DB200 for connection 1, DB201 for connection 2. Populate them per the table in §4.
  3. Assign unique Connection IDs. Set DB200.id = W#16#0001, DB201.id = W#16#0101 (or any other 16-bit value not already used by HMI/OP/PG connections — check the CPU's connection table in NetPro or HW Config → CPU Properties → Communication).
  4. Use unique remote ports. DB200.rem_tsap_id = port 2000 (0x07 0xD0), DB201.rem_tsap_id = port 2001 (0x07 0xD1). Verify the PC server is bound to both ports before commissioning.
  5. Call FB300 twice with rising-edge REQ. A typical pattern is:
    // OB1 cyclic
    A  M 10.0  // First-start trigger (rising edge only)
    FP M 10.1
    =  "TCON_DB".REQ  // ... mapped to FB300.REQ for conn 1
    
    A  M 10.2  // Second-start trigger
    FP M 10.3
    =  "TCON_DB2".REQ  // ... mapped to FB300.REQ for conn 2
    
    CALL FB 300, DB100   // instance for conn 1
    REQ    := M10.1
    ID     := W#16#0001  // (also visible in UDT)
    DONE   := M20.0
    ERROR  := M20.1
    STATUS := MW22
    
    CALL FB 300, DB101   // instance for conn 2
    REQ    := M10.3
    ID     := W#16#0101
    DONE   := M20.2
    ERROR  := M20.3
    STATUS := MW24
  6. Confirm the partner side. The PC application must listen() on both ports before the PLC issues connect(). A netstat -an | findstr :2000 from a Windows shell will show whether the sockets are in LISTENING state.
  7. Download and go online. Watch STATUS on both TCON calls. The expected sequence is 16#7000 (idle) → 16#7001 (job running) → 16#0000 (done) on a successful connection. A return of 16#7000 on the second call after a successful first call indicates the Connection ID collision; correct the ID and reload.

6. Connection Resource Planning on S7-315-2 PN/DP

CPU connection resources are finite and shared with all other communication partners: HMI, PG/PC online, S7 communication (PUT/GET), routing, and Open User Communication. For the 6ES7 315-2EH14-0AB0 (CPU 315-2 PN/DP, firmware V3.3):

Resource Quantity Notes
Total connection resources 16 (typical for CPU 315 PN/DP) Subdivided by connection type in HW Config.
Reserved for PG/OP communication 0–2 Configurable per CPU; do not set to zero unless the project is fully headless.
Reserved for S7 routing 0–4 Only if the CPU is used as a router between subnets.
Available for Open User Communication Remaining count Each TCON consumes one resource for the lifetime of the connection.
Watch the resource pool. If the CPU has fewer than 2 free connection resources when the second TCON is called, the call also returns 16#7000 indefinitely. Open HW Config → CPU Properties → Communication → Connection Resources and verify the "Open User Communication" row has at least two free slots before commissioning.

7. Active vs Passive Connection Establishment

The active_est BOOL inside UDT65 selects the endpoint role:

active_est PLC role Behavior
TRUE Active (client) PLC sends TCP SYN to the configured remote IP/port. Typical for PLC → PC scenarios.
FALSE Passive (server) PLC listens on the local TSAP and waits for an incoming SYN. Use when the PC application initiates the socket.

For two simultaneous sockets to a single PC, the most common pattern is both set to TRUE. The PLC then dials the same PC IP twice on two different remote ports. This works because the CPU picks a unique local port for each outgoing connection, even when the destination IP is identical. If the field environment is sensitive to outbound connection attempts (corporate firewall), use one active + one passive — but the ID uniqueness rule still applies.

8. Status Code Reference for FB300 TCON

STATUS (hex) Meaning Action
16#0000 Job complete, no error. Connection established. DONE = TRUE.
16#7000 No job active (initial state or job already completed and REQ has not been re-asserted). Expected on the first cycle. If it persists after REQ rising edge, the instance is wrong, the ID collides, or no connection resource is free.
16#7001 Job running. Wait. A successful call usually completes within one to three OB1 cycles after REQ.
16#7002 Job running, intermediate state. Same as 16#7001 for connection setup; informational only.
16#8085 Length/status error in TCON_PARAM. Check local_tsap_id_len, rem_staddr_len, rem_tsap_id_len; port must be 2 bytes, IPv4 must be 4 bytes.
16#8086 Parameter assignment error on IO area. Check that the TCON_PARAM DB is not optimised-access (must be standard DB if using classic S7-300 blocks).
16#80A1 Connection or port already in use. Remote port collision; change the port or close the other socket.
16#80A3 Connection being established. Transient; retry, or check for a stuck TCP half-open on the PC side.
16#80A4 IP address error in TCON_PARAM. Verify rem_staddr layout (big-endian, e.g. 192 168 0 50).
16#80A7 No free connection resource. Reduce active connections, or change the connection-resource split in HW Config.
16#80B3 Connection ID already in use. Direct evidence of a duplicate ID; reassign the Hi or Lo byte per §3.
16#80B4 Connection already established / no resource free for additional passive connections. Verify the connection list; close unused TCONs with FB301 TDISCON.

9. Verification Procedure

  1. Watch the CPU diagnostic buffer. Online → CPU → Diagnostic Buffer. A successful TCON produces entry "Connection established" with the configured ID. A failed attempt leaves a "Connection aborted / setup error" entry that points at the offending ID.
  2. Inspect the connection table. STEP 7 → NetPro → right-click the CPU → "Connection Status". Both connections should appear in state ESTABLISHED.
  3. Check the PC side. From a Windows shell, run netstat -ano | findstr :2000 and netstat -ano | findstr :2001. Each command should return one row with state ESTABLISHED and the PLC IP as the foreign address.
  4. Run a one-shot TSEND / TRCV cycle. Send a 4-byte handshake (e.g. 16#11 22 33 44) from the PC on port 2000, verify receipt via FB202 TRCV on the matching ID, and repeat on port 2001.
  5. Force a disconnect / reconnect cycle. Call FB301 TDISCON on connection 1, observe 16#0000, then re-trigger FB300. Both connections should re-establish without cycling the CPU.

10. Troubleshooting Matrix

Symptom Likely Cause Fix
Second TCON stuck on 16#7000, first works Duplicate Connection ID (Hi or Lo byte) Increment the Hi byte of the second UDT65 id field, e.g. W#16#0001 → W#16#0101.
Both TCONs stuck on 16#7000 Wrong instance DB or REQ not pulsed Re-generate instance DBs; verify REQ sees a rising edge in OB1.
TCON returns 16#80B3 ID collision with an HMI / PG / S7 connection Check the connection-resource table; pick an ID not used by WinCC / TIA Portal / routing.
TCON returns 16#80A1 Port already in use on the PC Run netstat -ano on the PC, kill the conflicting process, or change the port.
TCON returns 16#80A7 No free connection resource Reduce S7 / OP / routing reservation, or close idle connections with TDISCON.
TCON returns 16#8085 Wrong length in UDT65 (port ≠ 2 bytes, IP ≠ 4 bytes) Set rem_staddr_len = 4 for IPv4 and rem_tsap_id_len = 2 for TCP port.
PC sees SYN, immediately RST PC server not bound to that port, or firewall drops inbound Start the listener before triggering TCON; add firewall rule for ports 2000 and 2001.
Connection 1 OK, connection 2 resets every few minutes Keep-alive mismatch; PC closes idle sockets Send periodic application-level keep-alive from the PLC, or enable TCP keep-alive on the PC side.
STATUS alternates 16#7002 / 16#0000 in a loop REQ toggled every cycle, CPU tries to reconnect each pass Pulse REQ with a rising-edge flag, not a level signal.

11. Related Blocks and Companion Calls

FB / FC Name Purpose in the dual-TCP design
FB300 TCON Open connection One instance per Connection ID.
FB301 TDISCON Close connection One instance per Connection ID; share the same id WORD as the matching TCON.
FB202 TSEND Send data Match id to the relevant TCON; use distinct LEN / ADDR pointers if the payloads are different sizes.
FB203 TRCV Receive data One instance per connection; each can have its own receive buffer DB.
FC6 AG_SEND / FC5 AG_RECV Legacy ISO transport Not required for the dual-TCP scenario; included only for context.
UDT65 "TCON_PARAM" Parameter template Used to type the parameter DBs.

12. Field-Proven Notes

  • Match ID across TCON, TSEND, TRCV, TDISCON. A common follow-on error is to update the id in the TCON_PARAM DB but leave the literal ID input on the FB call set to the old value. The runtime accepts the literal; the UDT value is ignored. Always pass the same WORD via the FB's ID input.
  • Keep the parameter DB standard-access. On S7-300/400 classic blocks, optimised (sliced) access is not supported. If you allow STEP 7 to default to optimised access on a new DB, FB300 will return 16#8086 or behave erratically. Set the DB to Standard in the DB properties.
  • Update the CPU firmware if reusing IDs across reboots. On older firmware (V2.x of the 315-2 PN/DP), the connection table was not always cleared on a warm restart, leading to apparent ID collisions after a stop/run. Upgrade to V3.3 or later if your project is new.
  • Document the IDs in NetPro even if using Open User Communication. A placeholder S7 connection in NetPro with a free ID is a useful bookkeeping trick to avoid the Hi-byte collision in the first place.

13. FAQ

Why does my second TCON show STATUS 16#7000 and never connect?

The TCON's UDT65 id field is identical to the first TCON's id. Change the Hi byte (e.g. W#16#0001 → W#16#0101) so that every active TCON has a unique 16-bit Connection ID, then reload the project. This is the single most common cause of a stuck 16#7000 on the second socket.

How many TCP connections can the S7-315-2 PN/DP support simultaneously?

CPU 315-2 PN/DP (6ES7 315-2EH14-0AB0, firmware V3.x) has 16 total connection resources, shared with PG, OP, S7 routing, and Open User Communication. The exact number available for TCON depends on the reservation in HW Config → CPU Properties → Communication. Two TCON instances are well within budget as long as PG/OP reservations are kept at the default 1–2.

Do I need a different UDT65 field for the remote port, or can both connections use the same IP?

Both TCONs can use the same remote IP — the CPU distinguishes the two sockets by the unique local Connection ID and the unique remote port. The remote port is stored in rem_tsap_id as a 2-byte big-endian value, e.g. 0x07 0xD0 for 2000 and 0x07 0xD1 for 2001. Set rem_tsap_id_len = B#16#02 and rem_staddr_len = B#16#04 for IPv4.

Can I use the same instance DB for two TCON calls if I multiplex the Connection ID?

No. Each TCON call requires its own instance DB. The instance DB stores the multi-instance layout (internal state, RCV buffers, partner information). Sharing it will cause one call to overwrite the other and reproduce the 16#7000 / 16#80B3 symptom. Generate one instance DB per TCON via the FB's "Instance DB" context menu.

Do I have to use TSEND and TRCV after TCON, or can I keep the socket idle?

You can keep the socket idle; TCON only establishes the session. TSEND and TRCV are independent instructions that reference the same id WORD. For a long-lived idle session, the PC server may still apply a keep-alive timeout — send a one-byte heartbeat every 30–60 s from the application layer if the channel must survive aggressive timeouts.

Back to blog