Overview
PROFINET is positioned by PROFIBUS & PROFINET International (PI) as an open Industrial Ethernet standard for data acquisition and control, but the practical reality is that the full PROFINET CBA (Component Based Automation) stack is wrapped in DCOM, the specifications are paywalled, and the on-the-wire real-time frames (RTC, RT, IRT) are not exposed through any public Windows socket API. For an engineer who only needs to read and write process data to a SIMATIC S7-416 CPU from a Visual Basic client, the correct path is therefore not PROFINET at all, but the native open communication services built into the S7-400 firmware: ISO-on-TCP (RFC 1006), plain TCP, and UDP. These services ride on standard TCP/IP, accept any Winsock-capable client, do not require a PROFINET stack or DCOM, and are configured with the Step 7 "Open Communication" (OC) Wizard plus a small SCL function block on the PLC side.
This reference walks through the complete architecture, hardware compatibility (CP 443-1 PN vs. CP 343-1 / EM 243-1), the OC Wizard connection setup, the SCL server block, and a Visual Basic 6 / VB.NET client using the Winsock control. It also explains why PI's licensing model looks the way it does, and why an ActiveX/COM wrapper is essentially the only Windows-side alternative when you really do need CBA.
Why PROFINET Is Not a Socket Protocol
PROFINET defines three performance classes on top of Industrial Ethernet:
- NRT (Non-Real-Time) – standard TCP/IP, used for parameterization, diagnostics, and CBA RPC traffic. Latency ≈ 100 ms.
- RT (Real-Time) – Ethernet frames with VLAN priority and a PROFINET-specific EtherType (0x8892), no IP/UDP header. Latency ≈ 1–10 ms.
- IRT (Isochronous Real-Time) – scheduled by a master clock, used only for motion. Latency < 1 ms with jitter < 1 µs.
RT and IRT bypass the IP stack entirely. They are not addressable as socket endpoints, cannot be opened with socket()/connect(), and are offloaded to PROFINET ASICs on the CP or PN-CPU. NRT channels do use TCP/IP, but the only NRT application that PI publishes is the PROFINET CBA RPC/DCOM interface, which is a Microsoft-COM-specific binary protocol. There is no publicly documented plain-text or request/response NRT service that a Winsock client can call directly.
The reason the standard feels "secret" is therefore structural, not accidental:
- RT/IRT frame formats are defined in IEC 61784-2 and the PI specification "PROFINET IO – Technology and Application", distributed by PI to members and via paid download.
- CBA's wire format is DCOM, whose detailed spec is held by Microsoft and the Object Management Group. PI does not re-publish it; it ships the DCOM wrappers themselves.
- Conformance testing and the GSD/GSDML device-description mechanism are also PI-controlled, so a third-party stack cannot claim PROFINET compliance without joining PI.
Hardware Compatibility: Which CP Modules Support Open Communication?
The Open Communication (OC) services on the S7-400 require that the Ethernet interface – whether the CPU's integrated PN port or a communication processor (CP) – exposes the right firmware services. Empirical compatibility from the field is summarized below.
| Module | Order Number (6GK7-) | OC supported? | Notes |
|---|---|---|---|
| CPU 416-3 PN/DP integrated PROFINET port | 6ES7 416-3ER05-0AB0 (and later) | Yes | PN interface supports TCP, ISO-on-TCP, UDP, S7. |
| CP 443-1 PN | 6GK7 443-1EX20-0XE0 | Yes | PROFINET-capable CP, recommended for OC. |
| CP 443-1 Advanced | 6GK7 443-1GX20-0XE0 | Yes | Adds security, web diagnostics. |
| CP 443-1 (pre-PN) | 6GK7 443-1EX11-0XE0 | Yes | Original CP 443-1, ISO-on-TCP only, no NRT PROFINET. |
| CP 443-1 IT | 6GK7 443-1GX11-0XE0 | Yes | Adds HTTP/FTP server. |
| CP 343-1 (S7-300) | 6GK7 343-1EX11-0XE0 | No (for OC Wizard) | OC Wizard only generates blocks for PN modules. |
| EM 243-1 (S7-200) | 6ES7 243-1EX01-0XE0 | No (for OC Wizard) | ET 200S-style module, no OC support. |
Connection Types Available on the S7-400
NetPro exposes four transport types for open communication. Pick the one that matches your data rate, payload size, and client platform.
| Connection Type | Config ID | Transport | Port (default) | Max Payload | Best for |
|---|---|---|---|---|---|
| TCP (native) | unspecified (raw socket) | TCP/IP | Configurable (e.g. 2000) | ≤ 1460 bytes / send | Streamed binary, large messages. |
| ISO-on-TCP | 0x13B (RFC 1006) | TCP/IP + 4-byte TPDU header | 102 | ≤ 1452 bytes / send | Standard for S7 partner interfaces; firewalls friendly. |
| UDP | unspecified | UDP/IP | Configurable | ≤ 1472 bytes / datagram | Broadcast, low-overhead publish/subscribe. |
| ISO Transport (without IP) | n/a | OSI layer 4 only | n/a | ≤ 1452 bytes / send | Same subnet, no router, lowest overhead. |
For a VB client behind a corporate firewall, ISO-on-TCP on port 102 is the lowest-risk choice: the port is well known, the 4-byte TPDU prefix is trivial to encode, and the S7-400 firmware already knows how to multiplex it. For high-throughput telemetry where you control both ends, plain TCP on a custom port is simpler to debug with Wireshark because the payload starts immediately after the TCP header.
Prerequisites
- PLC side: S7-416 CPU (any -3 PN/DP variant) with STEP 7 V5.5 + SP4 or TIA Portal V15.1 and later. The CPU must have a PROFINET interface (integrated PN or CP 443-1 PN).
- Open Communication Wizard (OC Wizard): Add-on package installed on the STEP 7 PC. Free download from Siemens support (entry ID 25209116).
-
PC side: Windows 7/10/11 with a Winsock-capable development environment. Visual Basic 6 (with
MSWINSCK.OCX) or VB.NET (withSystem.Net.Sockets). - Network: Ethernet switch, 100 Mbit/s or better. Static IP addressing recommended. The PLC and PC must be on the same IP subnet unless you route TCP through a managed switch.
- Administrative rights on the engineering PC to install the OC Wizard and (if you target VB6) to register the Winsock OCX.
Step 1 – Configure the TCP Connection in NetPro
- Open the STEP 7 project that contains the S7-416 station.
- Launch NetPro from the project.
- Right-click the S7-400 CPU → Insert New Connection.
- Connection partner: Unspecified.
- Connection type: TCP connection (or ISO-on-TCP if you prefer RFC 1006).
- Local end point: the CPU or the CP 443-1 PN.
- Partner address: the IP address of the VB host (e.g. 192.168.0.50).
- Partner port: 2000 (or any free port you will open on the PC side).
- Local port: leave blank for the PLC (the firmware allocates one).
- Confirm and Save & Compile All (Ctrl+F9) to download the connection configuration to the CPU on next download.
NetPro writes a connection ID into the generated SDBs. You will need this ID (a small integer such as 1) when you call AG_SEND / AG_RECV in SCL.
Step 2 – Generate the OC Wizard Blocks
- Start the Open Communication Wizard from the STEP 7 start menu.
- Select the S7-400 station and the NetPro connection you just created.
- Choose the transport: TCP, ISO-on-TCP, or UDP.
- Set the maximum send/receive length (default 240 bytes; max 1460 for TCP, 1452 for ISO-on-TCP).
- Choose the protocol: Send/Receive (full-duplex) or Fetch/Write (S7 partner service, server-pulled).
- Select the SCL source library destination and click Generate.
The wizard drops a small SCL library into your project containing:
- An instance DB (DB100 by default) that holds the connection ID, status words, and the receive buffer.
- Two FBs (
FB100 SENDandFB101 RCV) that wrap the AG_SEND / AG_RECV system functions. - A ladder stub for OB1 that calls the FBs cyclically.
Drag the generated FBs into OB35 (the 100 ms cyclic OB) for deterministic timing, or leave them in OB1 if cycle time is not critical.
Step 3 – Server-Side SCL: The S7-400 Application Block
The OC Wizard gives you a transport. You still need an application protocol on top – a frame format that the VB client can build. The simplest possible framing is length-prefixed records:
- 4 bytes (big-endian UINT32): payload length N.
- N bytes: payload (function code + data).
Here is a minimal SCL server that exposes a 16-word data block and accepts read/write requests from the VB client. Function code 0x01 = read words, 0x02 = write words, 0x03 = read DB block name (returns "OK\n").
// SCL sample: server block for S7-416, calls OC-wizard FB100/FB101
FUNCTION_BLOCK "TCP_Server"
VAR
sSend : ARRAY[0..239] OF BYTE; // 240 byte transmit buffer
sRecv : ARRAY[0..239] OF BYTE; // 240 byte receive buffer
iLenReq : INT; // requested length from VB
iLenIn : INT; // bytes actually received
iLenOut : INT; // bytes to send
iStat : INT; // AG_RECV status
iErr : INT; // AG_SEND status
dbUser : BLOCK_DB; // handle to user DB (DB200)
END_VAR
BEGIN
// 1. Receive a frame
iStat := "RCV"( // FB101 from OC wizard
ID := 1, // NetPro connection ID
LEN := 240, // max bytes
DATA := sRecv,
NDR := iLenIn);
IF (iStat = 0) AND (iLenIn >= 4) THEN
// 2. Decode length prefix (big-endian)
iLenReq := (BYTE_TO_INT(sRecv[0]) * 16777216)
+ (BYTE_TO_INT(sRecv[1]) * 65536)
+ (BYTE_TO_INT(sRecv[2]) * 256)
+ BYTE_TO_INT(sRecv[3]);
// 3. Dispatch by function code (byte 4)
CASE sRecv[4] OF
16#01: // READ_WORDS
// 4-byte start index in sRecv[5..8]
sSend[0] := sRecv[5];
sSend[1] := sRecv[6];
sSend[2] := sRecv[7];
sSend[3] := sRecv[8];
sSend[4] := 16#01; // echo function code
sSend[5] := 16#00; // status OK
// copy 16 words from DB200.DBW[idx] into sSend[6..37]
iLenOut := 38;
16#02: // WRITE_WORDS
// index in sRecv[5..8], count in sRecv[9..10], data sRecv[11..]
sSend[0] := 16#00; sSend[1] := 16#00; sSend[2] := 16#00; sSend[3] := 16#04;
sSend[4] := 16#02;
sSend[5] := 16#00; // status OK
iLenOut := 6;
ELSE
sSend[0] := 16#00; sSend[1] := 16#00; sSend[2] := 16#00; sSend[3] := 16#02;
sSend[4] := 16#FF; // unknown function
sSend[5] := 16#01;
iLenOut := 6;
END_CASE;
// 4. Transmit
iErr := "SEND"( // FB100 from OC wizard
ID := 1,
LEN := iLenOut,
DATA := sSend,
DONE := iErr);
END_IF;
END_FUNCTION_BLOCK
Step 4 – Visual Basic 6 Client (Winsock Control)
For VB6, the canonical solution is the MSWINSCK.OCX Winsock control. Drop it on a form and use the following skeleton.
' VB6 client skeleton, ISO-on-TCP (port 102) to S7-416
Dim gConn As Boolean
Private Sub Form_Load()
Winsock1.Protocol = sckTCPProtocol
Winsock1.RemoteHost = "192.168.0.10" ' PLC IP
Winsock1.RemotePort = 102 ' ISO-on-TCP port
Winsock1.Connect
End Sub
Private Sub Winsock1_Connect()
gConn = True
ReadWords 0, 16 ' initial read of 16 words from offset 0
End Sub
Private Sub Winsock1_Close()
gConn = False
End Sub
Public Sub ReadWords(ByVal iIndex As Long, ByVal iCount As Integer)
Dim b(0 To 7) As Byte
Dim i As Integer
' Build length prefix (4 bytes, big-endian) = 5 (func + index + count)
b(0) = 0: b(1) = 0: b(2) = 0: b(3) = 5
b(4) = &H1 ' function code READ_WORDS
b(5) = (iIndex And &HFF000000) \ &H1000000 ' big-endian index
b(6) = (iIndex And &HFF0000) \ &H10000
b(7) = (iIndex And &HFF00) \ &H100
b(8) = iIndex And &HFF
' count would go into b(9..10) if your protocol needs it
If gConn Then Winsock1.SendData b
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim b() As Byte
Winsock1.GetData b, vbByte + vbArray, bytesTotal
' parse length, function, status, then payload
' ... project-specific handling ...
End Sub
For VB.NET, replace the Winsock control with System.Net.Sockets.TcpClient and NetworkStream; the wire format is identical.
Step 5 – VB.NET Client (System.Net.Sockets)
' VB.NET client skeleton
Imports System.Net.Sockets
Imports System.IO
Module PlcClient
Dim cli As TcpClient
Dim ns As NetworkStream
Const PLC_IP As String = "192.168.0.10"
Const PLC_PORT As Integer = 102
Sub Connect()
cli = New TcpClient(PLC_IP, PLC_PORT)
ns = cli.GetStream()
End Sub
Function ReadWords(idx As Integer, count As Integer) As Byte()
Dim pkt(9) As Byte
pkt(0) = 0 : pkt(1) = 0 : pkt(2) = 0 : pkt(3) = 6 ' length=6
pkt(4) = &H1 ' READ
pkt(5) = CByte((idx >> 24) And &HFF)
pkt(6) = CByte((idx >> 16) And &HFF)
pkt(7) = CByte((idx >> 8) And &HFF)
pkt(8) = CByte(idx And &HFF)
pkt(9) = CByte(count And &HFF)
ns.Write(pkt, 0, pkt.Length)
' 4-byte length prefix
Dim hdr(3) As Byte : ReadExact(ns, hdr, 4)
Dim n As Integer = (hdr(0) << 24) Or (hdr(1) << 16) Or (hdr(2) << 8) Or hdr(3)
Dim buf(n - 1) As Byte : ReadExact(ns, buf, n)
Return buf
End Function
Sub ReadExact(s As Stream, buf As Byte(), n As Integer)
Dim got As Integer = 0
While got < n
got += s.Read(buf, got, n - got)
End While
End Sub
End Module
Verification
-
Connection test. From the engineering PC, open a command prompt and run
telnet 192.168.0.10 102. A successful TCP handshake proves the CPU and CP 443-1 PN are accepting connections on port 102. -
Wireshark trace. Filter on
tcp.port==102. You should see the SYN/SYN-ACK/ACK three-way handshake, then length-prefixed application data. ISO-on-TCP frames will show the 4-byte TPDU header (00 00 00 xx 11 d7 ...) before the application data. -
OB1 status LEDs. The OC wizard's instance DB exposes two status words:
RCV.STATUSandSND.STATUS. A healthy connection reads 0 (W#16#0000). Common non-zero values are listed in the troubleshooting table below. - Read/write round-trip. From VB, request a known value (e.g. read 16 words starting at offset 0), then write that same value plus one back, then read again. If the third read returns the incremented value, the full request/response cycle is working.
Troubleshooting Matrix
| Symptom | AG_RECV / AG_SEND status | Likely cause | Fix |
|---|---|---|---|
| Winsock fails to connect | – | Wrong IP, wrong port, firewall on PC | Verify IP with ping, add firewall rule, confirm NetPro downloaded to PLC. |
| Connect OK, no data arrives | W#16#0000 (idle) | OC wizard not in OB1/OB35, or wrong connection ID | Place the generated FB calls in a cyclic OB, check ID parameter matches NetPro. |
| AG_RECV returns W#16#8081 / 80A1 | 0x8081 / 0x80A1 | Connection aborted, partner reset | Check partner IP, switch port, CP firmware status LEDs (SF/BF). |
| AG_SEND returns W#16#80C3 | 0x80C3 | Resource exhausted, too many sends in one OB cycle | Throttle send rate, or raise CP's connection resource count. |
| Data arrives but is shifted by 4 bytes | 0x0000 | Forgot to strip TPDU header on ISO-on-TCP | Remove the 4-byte RFC 1006 prefix before parsing; use plain TCP if you want no prefix. |
| VB6 "Winsock not registered" | – | MSWINSCK.OCX not registered | Run regsvr32 MSWINSCK.OCX as administrator. |
| OC wizard rejects module | – | Selected CP 343-1 or EM 243-1 | Use a PN-capable CP 443-1 or the CPU's integrated PN port. |
| SCL block compiles, but the OC wizard FB will not load | – | Firmware too old, OC blocks missing | Update CPU firmware to V5.x or V6.x; CPU 416 must be -3 PN/DP variant. |
Cross-Platform Notes (Win CE, Windows Mobile)
The whole reason an engineer considers a raw TCP/IP socket approach instead of a Siemens-supplied OPC server or DCOM wrapper is portability to a small embedded HMI or a Windows Mobile / Win CE device. Two practical constraints apply:
- DCOM is heavy. PI's PROFINET CBA wrapper requires DCOM, COM, and often an out-of-process server. Win CE 5/6 supports COM, but the full DCOM stack is optional and often stripped from BSPs. Windows Mobile 5/6 does not include DCOM at all.
-
ActiveX control availability. The "OC Wizard" generates a SIMATIC-side function block; the PC-side
MSWINSCK.OCXis part of Visual Basic 6, not Win CE. A Compact Framework (CF) app on Win CE must useSystem.Net.Sockets– which is exactly the VB.NET path shown above.
The TCP-socket approach therefore scales down better than the PROFINET/COM approach. A CF client connecting via ISO-on-TCP port 102 needs only the .NET Compact Framework 2.0 or later; the S7-416 server-side code is identical to the SCL block above.
PROFINET CBA vs. Native TCP/IP – When to Choose Which
| Criterion | PROFINET CBA (DCOM) | Native TCP/IP (OC Wizard) |
|---|---|---|
| Standardized | Yes (PI spec) | No (custom protocol on top of TCP) |
| Wire-level open | No (paywalled spec) | Yes (your own spec) |
| Multi-vendor interoperability | High | Low (you define the format) |
| Latency floor | ~10–50 ms (DCOM marshaling) | ~1–5 ms (one TCP round-trip) |
| Firewall friendly | Poor (dynamic ports, RPC) | Excellent (single port) |
| Debug with Wireshark | Hard (DCOM) | Trivial (plain TCP) |
| Mobile/CE support | Poor / none | Good |
| Engineering effort | Low if you have PI toolkit | Medium (custom frame format, error handling) |
| Licensing cost | PI membership + toolkit | Zero |
Pick PROFINET CBA when you must exchange data with a third-party controller or HMI that already speaks CBA. Pick native TCP/IP for any in-house tool, mobile HMI, or one-off data-acquisition job.
Performance Numbers (typical, S7-416-3 PN/DP, firmware V6.0)
- Single-frame round-trip, 240-byte payload, 100 Mbit/s, both ends on the same switch: 2–3 ms.
- Throughput with 1460-byte payloads, 100 ms OB35 cycle: ~7,000 read requests/second, limited by application FB processing, not the TCP stack.
- Maximum sustained connection count on CP 443-1 PN: 64 (32 of which are reserved for S7/HMI; the remainder are free for OC).
- AG_SEND / AG_RECV latency inside the CPU: ~0.4 ms per call when the CP's internal buffer is hit; ~1.2 ms when it spills to the user DB.
Common Pitfalls
- Mixing the two connection types in the same S7 program. An ISO-on-TCP port 102 connection and a plain TCP port 2000 connection can coexist, but the OC wizard's instance DBs must be assigned distinct connection IDs in NetPro.
- Forgetting to download the connection configuration. The SDBs containing the connection description live in the CPU, not in NetPro. A "Save & Compile" without "Download to Target" leaves the PLC with no listener on port 102.
-
Expecting AG_SEND to queue. AG_SEND returns
DONEafter the data is copied into the CP's internal buffer. If the partner is slow, the CP can refuse additional sends with status 0x80C3. Build a small back-pressure mechanism in the SCL block. - Trusting the OC wizard on every firmware. Siemens updates the wizard with each STEP 7 release. Re-generate the blocks after a STEP 7 upgrade; the generated FBs are not always backward compatible.
- Disabling the integrated PROFINET port. If the CPU 416 has both an integrated PN port and a CP 443-1, the wizard may attach the connection to the wrong interface. Pin the connection to a specific interface in NetPro.
Migration Path: From Custom TCP to PROFINET
If you later need to interoperate with PROFINET controllers from third parties, the cleanest migration is to keep the SCL server block as-is and add a PROFINET IO device image in the same CPU. The S7-416 with PROFINET firmware can run both PROFINET IO and the OC open communication in parallel, on the same physical port. The wizard-generated FBs and your custom SCL are independent of the PROFINET IO image; they share only the Ethernet MAC/PHY.
When interoperability is required, the alternative – exporting your server block as a PROFINET CBA component – requires the PI toolkit and a non-trivial modeling step in SIMATIC iMap. For most point-to-point PC links, the cost-benefit ratio favours keeping the TCP/IP path indefinitely.
References in This Article
Siemens KB 25209116, "Communication between S7-CPU and third-party device via TCP/IP", is the official entry point and the source of the connection-type, port, and max-payload figures cited above. The S7-400 Communication Function Manual (entry ID 1117396 in Siemens Support) documents AG_SEND, AG_RECV, AG_LSEND, and AG_LRECV, including the error-code matrix summarized in the troubleshooting table. PROFINET CBA architecture and conformance requirements are published by PROFIBUS & PROFINET International at the PI downloads portal.
FAQ
Can I open a raw TCP socket to a PROFINET device?
No. PROFINET RT and IRT frames use EtherType 0x8892 and do not carry an IP header, so they cannot be addressed with socket()/connect(). Only the NRT channel (used by PROFINET CBA's DCOM stack) accepts standard TCP/IP, and the only NRT application published by PI is the CBA RPC interface.
Why does the OC Wizard refuse the CP 343-1 and EM 243-1?
The wizard generates FBs that call AG_SEND and AG_RECV. These system functions are exposed only on PROFINET-capable CPs and on PROFINET-enabled CPU interfaces. CP 343-1 and EM 243-1 are S7-300 / S7-200 modules without PROFINET support, so the wizard blocks them. Use a CP 443-1 PN or the CPU 416-3 PN/DP's integrated port.
Is PROFINET really an open standard if the spec is paywalled?
The PROFINET specification is owned by PROFIBUS & PROFINET International and is available to PI members and via paid download to non-members. "Open" in this context means the standard is published and not vendor-locked – anyone can implement it after joining PI. The NRT wire format is fully defined; the RT/IRT frame layouts are also defined but require conformance testing against a PI-approved test lab.
What is the difference between ISO-on-TCP (port 102) and plain TCP for a S7-416?
ISO-on-TCP is TCP with the ISO Transport Service Access Point header defined in RFC 1006. The S7-400 firmware always uses port 102 for this service and prepends a 4-byte TPDU header to every message. Plain TCP is just a raw stream; you choose the port (e.g. 2000) and define your own framing. ISO-on-TCP is preferred for partner interoperability; plain TCP is preferred for high-throughput or simplified Wireshark decoding.
Can the S7-416 act as both a PROFINET IO device and a TCP server at the same time?
Yes. The PROFINET IO image and the open-communication TCP connections share the same Ethernet physical port but use independent firmware paths. The OC wizard's FBs and your SCL server block run in the CPU's user program, while PROFINET IO is handled by the PROFINET stack in the CPU or CP. Configure both in NetPro, assign distinct connection IDs, and download once.
Do I need a Siemens SIMATIC NET license to run AG_SEND / AG_RECV on the S7-400?
No. AG_SEND and AG_RECV are part of the S7-400 system firmware and are callable from SCL/ST/FBD/LAD without any additional license. The SIMATIC NET OPC server or the SOFTNET-S7 / S7-REDCONNECT packages are only required if you want a PC-side S7 protocol client or an OPC DA/UA server; for raw TCP/IP they are unnecessary.