如何在 COM 端口发送和接收之间进行协调
本文关键字:之间 协调 COM | 更新日期: 2023-09-27 18:34:26
我正在尝试重构一些超复杂的遗留代码,这些代码将数据从手持设备发送到手持设备上运行的应用程序,手持设备连接到PC上。
两个应用程序之间有一个遵循协议的"对话";服务器(在PC上运行的应用程序(根据客户端告诉它的内容进行响应,反之亦然。实际上,"对话"在这里可以看到大约三分之二。
无论如何,我的问题是:我怎样才能让客户端等待服务器响应而不中断它,或者认为它不会响应并且无法继续?这就是我现在拥有的:
public class FileXferLegacy : IFileXfer
{
private SerialPort cereal;
private String lastDataReceived;
private String receivedData;
. . .
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// This method will be called when there is data waiting in the port's buffer
try
{
receivedData += cereal.ReadLine();
lastDataReceived = receivedData;
ExceptionLoggingService.Instance.WriteLog(String.Format("Received {0} in FileXferLegacy.SendDataContentsAsXML", receivedData));
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
#region IFileFetchSend Members
. . .
public void SendDataContentsAsXML(string destinationPath, string data)
{
byte[] stuff;
ExceptionLoggingService.Instance.WriteLog("Reached
FileXferLegacy.SendDataContentsAsXML");
cereal.Open();
stuff = System.Text.UTF8Encoding.UTF8.GetBytes("PING" + "'n");
cereal.Write(stuff, 0, stuff.Length);
if (lastDataReceived.Contains("PING")) // Expecting "PING|ACKNOWLEDGE|"
{
stuff =
System.Text.UTF8Encoding.UTF8.GetBytes("LOGIN|foo|000003|LOC_HOST|PPP_PEER|1.4.0.42|bar" + "'n");
// TODO: replace this test data with dynamic data
cereal.Write(stuff, 0, stuff.Length);
}
if (lastDataReceived.Contains("JOIN|LEVEL")) // Expecting something like "JOIN|LEVEL|1
SETTING|ALT_ID|FALSE"
{
stuff = System.Text.UTF8Encoding.UTF8.GetBytes("HHTCOMMAND|GETHHTSUPDATE|");
cereal.Write(stuff, 0, stuff.Length);
}
. . .
String lastResponse = lastDataReceived; // Expecting something like
"RESULT|FILECOMPLETE|INV_000003_whatever(not identical to what was sent earlier!).XML"
// Parse out and do something with the filename ("INV_000003_whatever(not identical to
what was sent earlier!).XML" above)
}
如您所见,客户端/手持设备发送一个字符串;然后读取在DataReceived方法中分配的"lastDataReceived"。但是,如果存在延迟,并且"lastDataReceived"为空怎么办?我需要做什么来强制延迟(不要走极端,导致应用程序在缓慢中看起来像懒惰一样(?或者,如果我完全偏离基础,应该采取什么方式?
一种典型的方法是使用读取器线程,该线程通过阻止读取从端口中提取字节(尽管可以使用异步通知来完成(,并且一旦检测到整个消息已传递,它就会:
- 将它们放入阻塞队列(使用者阻止取消排队的调用,直到添加消息或达到超时
或
- 使用包含消息的事件通知侦听器。
这两者中的哪一个在很大程度上取决于这些消息的使用者。 上面的代码将从#1中受益,但如果使用者是UI线程,那么您应该查看#2。
该协议似乎是半双工的,因此通过对 Write/Readline 的同步调用重写它似乎是处理它的最简单方法。