所以,我过去曾经在大型系统上工作过,就像iso堆栈会话层一样,这样的东西对于我需要的东西来说太大了,但我确实对大局有所了解。我现在拥有的是一个串行点对点通信链路,其中一些组件正在丢弃数据(通常)。
因此,我将不得不编写自己的,可靠的传送系统,使用它进行传输。有人可以指出我的基本算法的方向,甚至提供一个线索,他们被称为什么?我曾尝试过谷歌,但最终还是研究了遗传算法等方面的理论。我需要基础知识。例如10-20行纯C。
答案 0 :(得分:1)
XMODEM。它已经很老了,很糟糕,但它在硬件和软件方面得到了广泛的支持,图书馆可用于各种语言和市场领域。
HDLC - 高级数据链路控制。它是在过去30年中诞生了许多可靠协议的协议,包括TCP / IP。您无法直接使用它,但它是如何开发自己的协议的模板。基本前提是:
对于特殊处理(同步),向数据包添加标志(通常只有一位就足够了,告诉数据包是特殊的并使用)。不要忘记CRC。
这两种协议都没有任何类型的会话支持。但是你可以通过简单地添加另一个层来引入一个 - 一个简单的状态机和一个计时器:
这就像会话控制一样简单。
答案 1 :(得分:0)
这个问题有(IMO)两个方面。
首先,如果数据被丢弃,那么我会首先考虑解决硬件问题,否则您将拥有GIGO
至于通信协议,您的帖子建议一个相当简单的系统?您想要验证数据(奇偶校验,sumcheck?)还是想要包含纠错?
如果只需要验证,我就可以使用RS232和CRC8 sumchecks运行可靠的系统 - 在这种情况下this StackOverflow page可能有帮助
答案 2 :(得分:0)
如果某些组件在串行点对点链接中丢弃数据,则代码中必定存在一些错误。
首先,您应该确认物理层的通信没有问题
其次,你需要一些关于数据通信理论的知识,比如ARQ(自动请求重传)
答案 3 :(得分:0)
进一步的想法,在考虑了你对前两个答案的回答之后......这确实表明了硬件问题,而且没有多少聪明的代码可以解决这个问题。
我建议你在链路上安装示波器,这有助于确定故障的位置。特别要看一下双方的波特率(Tx,Rx)以确保它们在规范内......自动波特率通常是个问题?!
但是看看辍学是否有规律,或者可以与任何其他活动同步。
答案 4 :(得分:0)
发送方;
///////////////////////////////////////// XBee logging
void dataLog(int idx, int t, float f)
{
ubyte stx[2] = { 0x10, 0x02 };
ubyte etx[2] = { 0x10, 0x03 };
nxtWriteRawHS(stx, 2, 1);
wait1Msec(1);
nxtWriteRawHS(idx, 2, 1);
wait1Msec(1);
nxtWriteRawHS(t, 2, 1);
wait1Msec(1);
nxtWriteRawHS(f, 4, 1);
wait1Msec(1);
nxtWriteRawHS(etx, 2, 1);
wait1Msec(1);
}
在接收方
void XBeeMonitorTask()
{
int[] lastTick = Enumerable.Repeat<int>(int.MaxValue, 10).ToArray();
int[] wrapCounter = new int[10];
while (!XBeeMonitorEnd)
{
if (XBee != null && XBee.BytesToRead >= expectedMessageSize)
{
// read a data element, parse, add it to collection, see above for message format
if (XBee.BaseStream.Read(XBeeIncoming, 0, expectedMessageSize) != expectedMessageSize)
throw new InvalidProgramException();
//System.Diagnostics.Trace.WriteLine(BitConverter.ToString(XBeeIncoming, 0, expectedMessageSize));
if ((XBeeIncoming[0] != 0x10 && XBeeIncoming[1] != 0x02) || // dle stx
(XBeeIncoming[10] != 0x10 && XBeeIncoming[11] != 0x03)) // dle etx
{
System.Diagnostics.Trace.WriteLine("recover sync");
while (true)
{
int b = XBee.BaseStream.ReadByte();
if (b == 0x10)
{
int c = XBee.BaseStream.ReadByte();
if (c == 0x03)
break; // realigned (maybe)
}
}
continue; // resume at loop start
}
UInt16 idx = BitConverter.ToUInt16(XBeeIncoming, 2);
UInt16 tick = BitConverter.ToUInt16(XBeeIncoming, 4);
Single val = BitConverter.ToSingle(XBeeIncoming, 6);
if (tick < lastTick[idx])
wrapCounter[idx]++;
lastTick[idx] = tick;
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => DataAdd(idx, tick * wrapCounter[idx], val)));
}
Thread.Sleep(2); // surely we can up with the NXT
}
}