第一个程序
普通服务端使用 <dlt698/app.hpp> 和 dlt698::dlt698:创建服务器、设置数据、启动即可,库管理监听、连接、会话和运行线程。
200F/属性2/索引0 是频率原始值,5000 表示 50.00 Hz。等待 Enter 只用于让应用保持运行,不需要手动驱动事件循环。串口把启动行换成 server.start_serial("COM3", 9600);运行中继续 server.set(...) 即可更新或首次发布其他属性。
构建后运行 dlt698_server,或 dlt698_server COM3。默认 TCP 会自动 LINK 登录并等待客户端 CONNECT;本地和预设关联、共享设备、布局/预算及退出约定见托管服务器与设备数据。
使用网络/串口调试助手的 TCP 模式连接默认示例,会收到 LINK 登录请求;未回复时约 5 秒后断开。直接手动 GET 请按 TCP 手动报文调试配置 local_preset 和匹配的 SA/CA;只建立 TCP 或只关闭心跳都不能完成协议关联。
客户端:连接后直接读取
客户端也不需要手动驱动 I/O。完整错误处理示例为 cpp/examples/app/client.cpp;在另一终端运行 dlt698_client,读取频率后自动断开。串口使用 client.open_serial("COM4", 9600),完整契约见托管客户端。
分层接口:内存中的完整会话
这个程序不需要网络和真实设备:两端都跑在内存通道上,客户机用同步客户机在同一个线程里驱动虚拟时钟。完整源码见 cpp/examples/service/memory_mutation.cpp。
构建后运行 dlt698_memory_mutation,输出:
逐段说明
执行器与通道。 ManualExecutor 是虚拟时钟执行器,只允许单线程使用。MemoryChannel::pair 返回一对已连接的通道,共享同一个执行器。真实设备上把 raw.first 换成 TCP 通道或串口通道即可,其余代码不变。
协议角色与拨号方向无关。 这里只给 terminal 设置了 Role::server。谁主动发起 TCP 连接是传输层的事,与协议角色独立配置。
对象目录。 register_object 的第一个参数是 schema:属性编号 2、类型 uint16、可读可写;方法编号 1,参数和返回类型都是 uint16。属性 writable 默认 false,必须显式打开。详见对象目录与 Provider。
方法回调不能捕获 shared_ptr。 目录持有 provider,provider 又被方法回调捕获会形成引用环。示例用 std::weak_ptr 打破环,并在调用时 lock()。
同步适配需要驱动函数。 第二个参数是 drive 回调,库会在每次等待时反复调用它来推进虚拟时钟,这样超时也能正常触发。不传 drive 时必须有其他线程持续驱动 IoRuntime::run()。在执行器回调里调用同步接口会直接返回 busy,避免死锁。
ObjectValue 是 variant。 get 返回的要么是 DAR(uint8_t),要么是精确类型 Data,必须先 std::holds_alternative 判断再取值。
下一步
- 需要读真实设备:看串口与串行链路和 TCP 通道。
- 需要处理分块、记录或 FollowReport:看 GET 与记录查询。
- 想理解报错来源:看 Result 与错误和错误码参考。