我有一个带Sparkfun WiFly shield的Arduino微控制器。
我在C#/ .NET中构建了一个简单的程序,使用System.Net.Sockets
连接到Arduino:
Socket Soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public void SendMsg(string msg)
{
try
{
byte[] buffer = StrToByteArray(msg);
if (Soc.Connected)
Soc.Send(buffer);
else
{
Soc.Connect(this.remoteIP);
Soc.Send(buffer);
}
}
catch (Exception e){}
}
关于我的arduino:
while(SpiSerial.available() > 0) {
byte b = SpiSerial.read();
Serial.println(b);
}
当套接字连接进行握手时,我得到:“ * OPEN * ”,当我关闭时,我得到:“ * CLOS * ”。
问题在于我将消息逐个字节地获取,有时我在一个while
循环中没有得到完整的消息。
因此,如果我使用上面在Arduino上显示的代码,我的串行终端看起来像:
*
O
P
E
N
*
T
E
S
T
*
C
L
O
S
*
那么如何找出PC试图发送的消息呢?
我知道我需要以某种方式使用一个特殊字节来表示我的消息结束。 (我不会在我的消息中使用的特殊字节,仅用于表示消息的结尾)
但是我该怎么办呢?要使用哪个字节?
答案 0 :(得分:2)
您需要在此设计自己的协议。您应该定义一个字节(最好是数据中不会出现的字节)来表示“开始”,然后您有三个选择:
第三个选项是最不可扩展和灵活的,当然,好像你已经有一个消息“OPEN”,你不能再添加一条新消息“OPENED”。
如果你选择第二个选项并定义一个“结束”字节,那么你需要担心如果它出现在你的数据中那么转义该字节(或者使用另一个保证不在你数据中的字节)。
答案 1 :(得分:0)
查看您当前的示例,一个很好的起点是简单地为每条消息添加长度前缀。
如果要支持长消息,可以使用2字节长度的前缀,然后读取前2个字节以获取长度,然后继续从套接字读取,直到读取长度指示的字节数为止前缀。
一旦你读完了一条完整的信息,你就会回来期待读取下一条信息的长度前缀,依此类推,直到其中一方终止通信为止。
当然,在所有这些之间,您需要检查错误情况,例如一端的套接字过早关闭等,以及如何处理可能导致套接字过早关闭的潜在部分消息。