1

所以,我过去曾在大型系统上工作过,比如 iso 堆栈会话层,类似的东西对于我的需要来说太大了,但我确实对大局有所了解。我现在拥有的是一个串行点对点通信链路,其中某些组件(通常)正在丢弃数据。

因此,我将不得不编写自己的、可靠的交付系统,并将其用于运输。有人可以为我指出基本算法的方向,甚至可以提供关于它们被称为什么的线索吗?我尝试了谷歌,但最终得到了关于遗传算法等的研究生理论。我需要基础知识。例如 10-20 行纯 C。

4

5 回答 5

1
  1. 调制解调器。它很旧,很糟糕,但它在硬件和软件上都得到了广泛的支持,几乎所有语言和市场利基都可以使用库。

  2. HDLC - 高级数据链路控制。在过去的 3 年中,它催生了许多可靠的协议,包括 TCP/IP。您不能直接使用它,但它是如何开发自己的协议的模板。基本前提是:

    • 每个数据字节(或数据包)都有编号
    • 通信双方在本地维护两个号码:上次接收和上次发送
    • 每个数据包都包含两个数字的副本
    • 每个成功的传输都通过发回一个带有更新数字的空(或非)数据包来确认
    • 如果在某个超时时间内未确认传输,请再次发送。

    对于特殊处理(同步),向数据包添加标志(通常只有一位就足够了,以告知数据包是特殊的并使用)。不要忘记CRC。


两种协议都没有任何类型的会话支持。但是您可以通过简单地添加另一层来引入一个 - 一个简单的状态机和一个计时器:

  • 会话以一个特殊的数据包开始
  • 在指定的超时时间内应该至少有一个(可能是空的)数据包
  • 如果本端在timeout/2内没有发送数据包,则发送一个空数据包
  • 如果在超时时间内没有从通信的另一端看到数据包,则会话已终止
  • 可以使用另一个特殊的数据包来优雅地终止会话

这和会话控制一样简单。

于 2015-01-29T09:09:42.957 回答
0

这个问题有(IMO)两个方面。

首先,如果数据被丢弃,那么我会先解决硬件问题,否则你将拥有 GIGO

至于通信协议,您的帖子建议使用一个相当简单的系统?您是要验证数据(奇偶校验、sumcheck?)还是要包括纠错?

如果只需要验证,我就可以使用 RS232 和 CRC8 sumchecks 运行可靠的系统——在这种情况下,这个 StackOverflow 页面可能会有所帮助

于 2012-08-27T06:56:30.553 回答
0

如果某些组件在串行点对点链接中丢弃数据,那么您的代码中肯定存在一些错误。

首先要确认物理层的通信没有问题

其次,您需要一些有关数据通信理论的知识,例如 ARQ(自动请求重传)

于 2012-08-27T07:03:54.217 回答
0

进一步的想法,在考虑了您对前两个答案的回应之后......这确实表明存在硬件问题,并且没有任何聪明的代码可以解决这个问题。

我建议您将示波器连接到链路上,这应该有助于确定故障所在。特别要查看两侧(Tx、Rx)的波特率,以确保它们在规格范围内……自动波特率经常是个问题?!

但是看看辍学是否是正常的,或者可以与任何其他活动同步。

于 2012-09-09T19:08:04.633 回答
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
            }
        }
于 2012-09-10T14:23:46.170 回答