TCP / UDP 通道
AddTcpClient 打开 TCP 连接,与串口、虚拟通道一样呈现为 IChannel。
builder.AddTcpClient("plc", "192.168.1.10", 502);
需要修改连接超时:
builder.AddTcpClient("plc", options =>
{
options.Host = "192.168.1.10";
options.Port = 502;
options.ConnectTimeoutMilliseconds = 2000;
});
默认端口是 502,适合 Modbus TCP。其它二进制协议也可以使用,再叠加 自定义帧。
TCP 服务端
AddTcpServer 用于监听本地 TCP 端口,适合设备或下位机主动连接上位机的场景。所有客户端发来的字节流都会触发 DataReceived。
builder.AddTcpServer("listener", localPort: 1502);
如果端口写 0,系统会自动分配临时端口;通道打开后可读取实际端口:
var listener = (TcpServerChannel)app.Channels.Get("listener");
await app.StartAsync();
Console.WriteLine(listener.LocalEndPoint?.Port);
无参 WriteAsync 仍回复最近一次发来数据的客户端。多客户端时应使用事件里的 RemoteEndPoint,或把通道当作 ISessionChannel:
listener.DataReceived += async (_, e) =>
{
if (e.RemoteEndPoint is { } remote)
{
await listener.WriteAsync(remote, e.Data);
return;
}
await listener.WriteAsync(e.Data);
};
需要主动推送到所有已连接客户端时,使用 BroadcastAsync。RemoteEndPoints 可用于显示当前客户端列表。
foreach (var endpoint in listener.RemoteEndPoints)
{
Console.WriteLine(endpoint);
}
await listener.BroadcastAsync("SYNC"u8.ToArray());
BroadcastAsync 支持取消。调用方取消会原样抛出 OperationCanceledException,不会把通道标为 Faulted,也不会因为一次取消就移除仍然连接的客户端。
可运行示例:samples/Zeus.Samples.Console.TcpServer。该示例在本机监听临时端口,演示客户端连接、回复最近发送方、广播和报文追踪。
JSON 配置可以写成:
{
"channels": [
{
"name": "listener",
"type": "tcp-server",
"options": {
"localAddress": "0.0.0.0",
"localPort": 1502
}
}
]
}
UDP 客户端
AddUdpClient 面向固定对端发送和接收 UDP 数据报。每个收到的数据报都会触发一次 DataReceived,业务代码仍然只依赖 IChannel。
builder.AddUdpClient("sensor", "192.168.1.20", 1502);
需要固定本地端口时使用选项回调:
builder.AddUdpClient("sensor", options =>
{
options.Host = "192.168.1.20";
options.Port = 1502;
options.LocalPort = 1502;
});
UDP 不建立连接,也不保证送达、顺序或重传。如果现场协议需要请求应答,请在上层协议里设置超时和重试。
UDP 服务端
AddUdpServer 用于监听本地 UDP 端口,适合设备主动上报、广播转发或上位机作为简易应答端。每个收到的数据报都会触发一次 DataReceived。
builder.AddUdpServer("listener", localPort: 1502);
如果端口写 0,系统会自动分配临时端口;通道打开后可读取实际端口:
var listener = (UdpServerChannel)app.Channels.Get("listener");
await app.StartAsync();
Console.WriteLine(listener.LocalEndPoint?.Port);
无参 WriteAsync 仍回复最近一次发来数据报的远端。多客户端时应使用 e.RemoteEndPoint:
listener.DataReceived += async (_, e) =>
{
if (e.RemoteEndPoint is { } remote)
{
await listener.WriteAsync(remote, e.Data);
return;
}
await listener.WriteAsync(e.Data);
};
JSON 配置可以写成:
{
"channels": [
{
"name": "listener",
"type": "udp-server",
"options": {
"localAddress": "0.0.0.0",
"localPort": 1502
}
}
]
}
选项
TCP
| 属性 | 默认 | 说明 |
|---|---|---|
Host | 127.0.0.1 | 主机名或 IP |
Port | 502 | 对端端口 |
ConnectTimeoutMilliseconds | 3000 | 连接超时 |
接收在后台进行。对端关闭连接后,通道进入 Faulted;宿主运行中默认会按退避自动重连。
TCP 服务端
| 属性 | 默认 | 说明 |
|---|---|---|
LocalAddress | 0.0.0.0 | 本地监听地址 |
LocalPort | 502 | 本地监听端口,0 表示系统自动分配 |
Backlog | 100 | 监听队列长度 |
ReceiveBufferSize | 8192 | 系统接收缓冲区大小 |
客户端断开只会移除该客户端,不会让整个服务端通道进入 Faulted。监听套接字本身失败时,通道才会进入 Faulted。
UDP 客户端
| 属性 | 默认 | 说明 |
|---|---|---|
Host | 127.0.0.1 | 对端主机名或 IP |
Port | 502 | 对端端口 |
LocalPort | 0 | 本地绑定端口,0 表示系统自动分配 |
ReceiveBufferSize | 8192 | 系统接收缓冲区大小 |
UDP 服务端
| 属性 | 默认 | 说明 |
|---|---|---|
LocalAddress | 0.0.0.0 | 本地监听地址 |
LocalPort | 502 | 本地监听端口,0 表示系统自动分配 |
ReceiveBufferSize | 8192 | 系统接收缓冲区大小 |
连接或收发失败时请确认对端监听、防火墙放行和本地端口未被占用;联调阶段可以改用虚拟通道。