将字符包读入数组,然后解析

时间:2018-08-31 16:51:47

标签: c arrays function pointers char

因此,一开始我很抱歉成为新手。我尝试自己解决这个问题并搜索其他答案,但我什至不确定自己到底要搜索什么。我发现this是一个有用的答案,但只是希望进一步澄清。

我正在与几个开发委员会合作,努力使他们互相交谈。我需要与之讨论的一个板提供了一些我一直在尝试的示例代码。 TX函数工作正常,只是我对C不够熟悉,无法完全了解我在做什么。

他们提供的RX功能是:

int recv_packet(char *p, int len){
    char c;
    int received = 0;
    /* sit in a loop reading bytes until we put together
    * a whole packet.
    * Make sure not to copy them into the packet if we
    * run out of room.
    */
    while(1) {
        /* get a character to process
        */
        c = UART_GetChar();
        /* handle bytestuffing if necessary
        */
        switch(c) {
            /* if it's an END character then we're done with
            * the packet
            */
            case END:
                /* a minor optimization: if there is no
                * data in the packet, ignore it. This is
                * meant to avoid bothering IP with all
                * the empty packets generated by the
                * duplicate END characters which are in
                * turn sent to try to detect line noise.
                */
                if(received)
                    return received;
                else
                    break;
            /* if it's the same code as an ESC character, wait
            * and get another character and then figure out
            * what to store in the packet based on that.
            */
            case ESC:
                c = UART_GetChar();
                /* if "c" is not one of these two, then we
                * have a protocol violation. The best bet
                * seems to be to leave the byte alone and
                * just stuff it into the packet
                */
                switch(c) {
                    case ESC_END:
                        c = END;
                        break;
                    case ESC_ESC:
                        c = ESC;
                        break;
                }
            /* here we fall into the default handler and let
            * it store the character for us
            */
            default:
                if(received < len)
                p[received++] = c;
        }
    }
}

然后根据我发现的答案,我可以使用类似的功能来调用它

int main() {
    char arr[10] = {0};
    recv_packet(arr, 10);
    /*then parse it somehow-- 
    * I'll figure this out on my own, 
    * but for now I just want to read it all 
    * into an array.
    */
    parse_function(arr);
}

因此,如果您完成了所有工作...。我的主要问题是,如果我使长度小于需要接收的消息,如何防止阵列填满?我正在使用C与之交谈的设备将发回一系列以0xC0开头和结尾的十六进制字符(否则在其他代码中定义为“ END”),但是中间是一堆乱七八糟的东西,是从设备取决于我在send_packet中发送的内容。我想我可以将arr设置得很大,以防万一,但是我想知道在这种情况下适当的编码将决定什么。

2 个答案:

答案 0 :(得分:0)

我说您需要更多分析-2个步骤。 第一步:定义(或尊重)您打算使用的协议。协议必须定义最大包长度,没有更大的包是合法的。 您发布的例程已经受到保护,可以防止太大的数据包,但是无法检查其有效性。该协议可以为数据包定义一个固定的长度,或者为不同类型的数据包定义不同的长度,等等,您必须检查它们。

第二步:一次获取一个数据包,对其进行管理,然后重新开始。

有两种技术可以在上述简单情况下提供帮助。如果您需要传输大量数据,请为一个(大)逻辑数据块使用多个数据包。例如,如果您接收数据并将其存储在其他地方(例如闪存),则接收 all 数据然后存储 all 并不好。一次做一次,也许还要进行一致性检查。

第二个建议:如果您担心在管理另一个数据包时可能会丢失一个数据包,则必须使用中断(也许您已经在这样做了)。因此,您可以在处理数据的同时接收 。有时,双缓冲区可以提供帮助。接收数据包,将其放入辅助(双)缓冲区,然后在分析辅助缓冲区时再次开始接收。甚至可以直接在中断例程中进行此操作(切换缓冲区而不是在缓冲区之间进行复制),但这可能不在主题之列。

-注释后更新-

实际上,当涉及数据传输时,在接收到数据的同时处理输入数据 是最有效(并且可能是安全的)方法。无论如何,您都必须接收和解析(两件事要做),因此代码不会变得更大。您不会在等待数据时浪费时间,也不会在浪费不必要的内存。至少,协议的某些低级部分应在接收时完成(您发布的例程使用转义符执行某些操作)。正如您提到的,接收时,有时您会知道会收到多少数据。

答案 1 :(得分:-1)

  

我想我可以将arr设置得非常大,以防万一,但是我想知道在这种情况下适当的编码会决定什么。

这是正确的-从I / O读取数据时,无论是网络,文件系统等,通常都使用缓冲区,并使其大于预期的传入消息大小。

因此,您可以代替char arr[10] = {0};

char arr[10000];

只需重复使用它,而不必担心空间不足。