跳到主要内容

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​

属性默认说明
Host127.0.0.1主机名或 IP
Port502对端端口
ConnectTimeoutMilliseconds3000连接超时

接收在后台进行。对端关闭连接后,通道进入 Faulted;宿主运行中默认会按退避自动重连。

TCP 服务端​

属性默认说明
LocalAddress0.0.0.0本地监听地址
LocalPort502本地监听端口,0 表示系统自动分配
Backlog100监听队列长度
ReceiveBufferSize8192系统接收缓冲区大小

客户端断开只会移除该客户端,不会让整个服务端通道进入 Faulted。监听套接字本身失败时,通道才会进入 Faulted。

UDP 客户端​

属性默认说明
Host127.0.0.1对端主机名或 IP
Port502对端端口
LocalPort0本地绑定端口,0 表示系统自动分配
ReceiveBufferSize8192系统接收缓冲区大小

UDP 服务端​

属性默认说明
LocalAddress0.0.0.0本地监听地址
LocalPort502本地监听端口,0 表示系统自动分配
ReceiveBufferSize8192系统接收缓冲区大小

连接或收发失败时请确认对端监听、防火墙放行和本地端口未被占用;联调阶段可以改用虚拟通道。