我有一个特殊的问题。
我需要用来与串行设备通信的自定义协议的工作方式如下,我使用的是标准 ASCII 缩写。
- -> 我的程序发送 SOH 开始传输
- -> 我的程序发送了一个 STX+data+ETX 的数据包(我实际上一次发送了 SOH 和这个数据包)
- <- 设备发回一个 ACK 以确认他已收到数据包
- -> 现在我的程序发送一个 EOT 来表示传输结束
如果消息是一个期望得到答复的请求,则设备会发回数据。因为这种方式SerialPort.DataReceived
有效,所以我必须手动将收到的消息拼凑在一起。它有点像这样:
- <- 设备发送 SOH+STX+数据
- <- 设备发送额外的字节,以 ETX 结尾
- -> 一旦收到完整的包,我的程序就会发送 ACK
- <- 设备发送 EOT
这基本上是这两个通信的方式,除了丢失的数据包和 NAK 和那些东西,但我不想让它太复杂。
我的问题是:如何将发送完整消息或接收完整消息包装成原子操作?我不想要的是我的程序在将收到的消息粘合在一起时发送新消息。
我试过使用Monitor.Enter()
,Monitor.Exit()
但收到的事件是在不同的线程上调用的,所以没有骰子。
我还尝试使用Semaphore
仅具有 1 个资源的资源,semaphore.WaitOne()
在发送或接收开始时调用,并semaphore.Release()
在发送 EOT 和从设备收到 EOT 后调用。这也不是很好。
有没有办法更好地做到这一点?