跳到主要内容

TCP

Overview

PortDIC provides a TCP communication handler (ITCPHandler) backed by porttcp.dll (Rust FFI). It supports both client and server modes, background reading, automatic reconnection, and file logging.

Each [TCP] class registers its own independent TCP connection — multiple connections can coexist in the same application.


Quick Setup

1. Define a TCP handler class

using Portdic;
using Portdic.TCP;

[TCP]
public class MyTcpClient
{
[TCPHandler]
public ITCPHandler handler { get; set; } = null!;

[Preset]
private void Preset()
{
handler.SetMode(TcpMode.Client);
handler.SetHost("192.168.1.100");
handler.SetPort(5000);
handler.SetTimeout(5000);

handler.OnDataReceived += OnData;
handler.OnEvent += OnEvent;
}

private void OnData(string name, byte[] data, string hex)
{
Console.WriteLine($"[{name}] Received: {hex}");
}

private void OnEvent(string name, string eventType, string description)
{
Console.WriteLine($"[{name}] {eventType}: {description}");
}
}

2. Register and run

Port.Add<MyTcpClient>("tcp_client1");
Port.Run();

Client vs Server Mode

TCP Client

[TCP]
public class TcpClient_Example
{
[TCPHandler]
public ITCPHandler handler { get; set; } = null!;

[Preset]
private void Preset()
{
handler.SetMode(TcpMode.Client);
handler.SetHost("192.168.1.100");
handler.SetPort(5000);
handler.SetTimeout(5000); // connect timeout (ms)
handler.SetReconnection(1000, 0); // retry every 1s, infinite retries

handler.OnDataReceived += OnData;
handler.OnEvent += OnEvent;
}

// Send data after CONNECTED event
private void OnEvent(string name, string eventType, string description)
{
if (eventType == "CONNECTED")
handler.Send("Hello Server\r\n");
}

private void OnData(string name, byte[] data, string hex)
{
Console.WriteLine($"[{name}] {hex}");
}
}

Port.Add<TcpClient_Example>("client1");

TCP Server

[TCP]
public class TcpServer_Example
{
[TCPHandler]
public ITCPHandler handler { get; set; } = null!;

[Preset]
private void Preset()
{
handler.SetMode(TcpMode.Server);
handler.SetHost("0.0.0.0"); // listen on all interfaces
handler.SetPort(6000);

handler.OnDataReceived += OnData;
handler.OnEvent += OnEvent;
}

private void OnData(string name, byte[] data, string hex)
{
// Echo back to all connected clients
handler.Send(data);
}

private void OnEvent(string name, string eventType, string description)
{
Console.WriteLine($"[{name}] {eventType}: {description}");
}
}

Port.Add<TcpServer_Example>("server1");

Multiple Connections

Each [TCP] class registration creates its own independent connection:

Port.Add<TcpHelper_Client>("tcp_plc1");
Port.Add<TcpHelper_Client>("tcp_plc2");
Port.Add<TcpHelper_Server>("tcp_server1");

The registration key (e.g., "tcp_plc1") is the name passed to OnDataReceived and OnEvent callbacks.


API Reference

Attributes

AttributeTargetDescription
[TCP]ClassMarks the class as a TCP handler container
[TCPHandler]PropertyInjects the ITCPHandler instance
[Preset]MethodCalled before Open() to configure the handler

Configuration methods

MethodDescription
SetMode(TcpMode mode)TcpMode.Client or TcpMode.Server
SetHost(string host)Target IP for client; "0.0.0.0" for server listening on all interfaces
SetPort(int port)Port number
SetTimeout(int timeoutMs)Connect timeout in ms (client only). Default: 5000

Connection methods

MethodReturnsDescription
Open()ERROR_CODEConnect (client) or start listening (server). Starts background reading automatically
Close()ERROR_CODEDisconnect or stop server
IsConnectedbooltrue if connection or server is active

Send methods

MethodReturnsDescription
Send(byte[] data)intSend raw bytes. In server mode, broadcasts to all clients
Send(string text)intSend UTF-8 string

Returns the number of bytes sent, or -1 on error.

Reading

MethodDescription
StartReading()Start background reading (auto-called by Open())
StopReading()Stop background reading

Reconnection (client mode)

MethodDescription
SetReconnection(uint intervalMs, uint maxRetries)Enable auto-reconnect with exponential backoff (intervalMs * 2^attempt, max 30s). maxRetries = 0 = infinite
TryReconnect()Manually restart reconnect loop after GIVE_UP event

Logging

MethodDescription
SetLogger(string rootPath)Enable hourly-rotated SEND/RECV log files at rootPath
SetLogger(string rootPath, PortLogConfiguration conf)Logging with custom rotation/retention settings
WriteLog(string v)Write a custom entry to the active log file

Log file format: tcp_{name}_{date}_{hour}.log


Events

OnDataReceived

Fired when data arrives from the remote peer.

handler.OnDataReceived += (string name, byte[] data, string hex) =>
{
Console.WriteLine($"[{name}] {data.Length} bytes: {hex}");
};
ParameterDescription
nameRegistration key (e.g., "tcp_client1")
dataRaw received bytes
hexHex string (e.g., "48 65 6C 6C 6F")

OnEvent

Fired on connection state changes.

handler.OnEvent += (string name, string eventType, string description) =>
{
Console.WriteLine($"[{name}] {eventType}: {description}");
};
eventTypeTriggered When
CONNECTEDClient connected to server
DISCONNECTEDConnection closed
ERRORConnection error (description contains detail)
LISTENINGServer started and is accepting connections
CLIENT_CONNECTEDA client connected to the server
CLIENT_DISCONNECTEDA client disconnected from the server
GIVE_UPReconnect retries exhausted (maxRetries exceeded)

Error Codes

CodeValueMeaning
ERR_CODE_NO_ERROR1Success
ERR_CODE_OPEN-1Open/connect failed
ERR_CODE_DLL_NOT_LOADED-2porttcp.dll not loaded
ERR_CODE_PORTNAME_EMPTY-3Connection name not set
ERR_CODE_DLL_FUNC_NOT_CONFIRM-4Required DLL function unavailable
ERR_CODE_CONNECT_FAILED-5Connection attempt failed

  • Serial — RS232/RS485 serial port communication
  • MQTT — Lightweight pub/sub messaging
  • SECS/GEM — Semiconductor equipment protocol