将字符串包读入数组然后解析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将字符串包读入数组然后解析相关的知识,希望对你有一定的参考价值。
所以,首先,我为此成为一个新手而道歉。我试图自己解决这个问题并搜索其他答案,但我甚至不确定究竟要搜索什么。我发现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
非常大以防万一,但我想知道在这种情况下适当的编码会有什么作用。
我说你需要更多分析 - 两步。第一步:定义(或尊重)您打算使用的协议。协议必须定义最大数据包长度,并且没有更大的数据包是合法的。您发布的例程已经受到过多大数据包的保护,但没有检查有效性。协议可以为数据包定义固定长度,或为不同类型的数据包定义不同的长度,或者其他任何内容,您必须检查它们。
第二步:一次获取一个数据包,管理它,然后重新开始。
有两种技术可以帮助解决上述简单情况。如果您需要传输大量数据,请为一大块逻辑数据使用多个数据包;例如,如果您接收数据并将其存储在其他位置(例如闪存),则接收所有数据然后存储所有数据并不好。一次做一件,也许连同一致性检查。
第二个建议:如果您担心在管理另一个数据包时可能丢失数据包,则必须使用中断(可能您已经在执行此操作)。因此,您可以在操作数据时收到。有时,双缓冲可以提供帮助;接收数据包,将其放入辅助(双)缓冲区,在分析辅助缓冲区时再次启动接收。这甚至可以直接在中断例程中进行(切换缓冲区而不是在它们之间进行复制),但这可能超出了主题范围。
- 以下评论后更新 -
实际上,当涉及数据传输时,在接收数据传输时处理传入数据是最有效(并且可能是安全的)方式。无论如何你必须接收和解析(两件事要做),所以代码不会变大。您不必在等待数据时浪费时间,也不会浪费不必要的内存。至少,协议的某些低级部分应该在接收时完成(您发布的例程会执行转义)。正如您所提到的,在接收时,您有时可以知道将会有多少数据。
我想我可以做得非常大以防万一,但我想知道在这种情况下适当的编码会有什么作用。
这是正确的 - 当从I / O读取时,无论是网络,文件系统等,通常使用缓冲区,并使其大于您期望的传入消息大小。
所以你可以做,而不是char arr[10] = {0};
char arr[10000];
只是重复使用它而不用担心用完房间。
以上是关于将字符串包读入数组然后解析的主要内容,如果未能解决你的问题,请参考以下文章