所以我正在使用CAN utils使用this CANopenNode即时通讯通过.c程序文件进行转储。
我的接收方代码看起来像这样
char raw_message[47], message_id[4], message_data[17];
fp = popen("candump vcan0 -L", "r");
if( fp == NULL )
{
printf("Failed to run CANDUMP for VCAN0");
exit(1);
}
while ( fgets(raw_message, sizeof(raw_message), fp) )
{
if( isspace(raw_message[0]) )
{
}
else
{
//GETTING THE ACTUAL MESSAGE = ID+DATA
cid = 0;
cdata = 0;
for(i=26; i<46; i++)
{
if( i<29 )
{
message_id[cid] = raw_message[i];
cid++;
}
else if ( i==29 )
message_id[cid] = '\0';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '\0';
//END OF GETTING MESSAGE
fprintf(stdout,"%s\n",raw_message);
fflush(stdout);
}
}
pclose(fp);
并且我正在运行要发送的shell脚本
echo "Start"
i=0;
while [ $i -le 5 ] ;
do
#echo "sent"
cansend vcan0 123#0801010101010101
let i=$i+1
done
exit 0
我试图做的是从消息的实际数据中分离ID。事实是,正如您所看到的,仅当raw_message空间的第一个插槽没有空间导致我收到一条消息时,才使用fgets获取它,然后得到“'然后消息,然后是'”,然后继续。仅当我使用if(isspace)似乎可以工作并且在注释上添加命令“ fprintf(stdout,“%s \ n”,raw_message);“时,停止工作。我尝试了多种解决方案,但似乎无济于事。这样做有什么特殊原因吗?我是在做错什么,还是在做CANUtils?
当我使用issspace()时输出(输出与在bash上运行candump时的输出相同{}
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101
(1585149182.555930) vcan0 123#0801010101010101
(1585149182.559413) vcan0 123#0801010101010101
(1585149182.560687) vcan0 123#0801010101010101
(1585149182.561604) vcan0 123#0801010101010101
我不使用时的输出
while ( fgets(raw_message, sizeof(raw_message), fpdump) )
{
// if( isspace(raw_message[0]) )
// {
// }
// else
{
//GETTING THE ACTUAL MESSAGE = ID+DATA
cid = 0;
cdata = 0;
for(i=26; i<46; i++)
{
if( i<29 )
{
message_id[cid] = raw_message[i];
cid++;
}
else if ( i==29 )
message_id[cid] = '\0';
else if ( i>29 )
{
message_data[cdata] = raw_message[i];
cdata++;
}
}
message_data[16] = '\0';
//END OF GETTING MESSAGE
fprintf(stdout,"%s\n",raw_message);
fflush(stdout);
}
}
输出:
(1585149305.257591) vcan0 123#0801010101010101
(1585149305.258339) vcan0 123#0801010101010101
(1585149305.259055) vcan0 123#0801010101010101
(1585149305.259651) vcan0 123#0801010101010101
(1585149305.260280) vcan0 123#0801010101010101
(1585149305.260860) vcan0 123#0801010101010101
问题中显示的示例数据
(1585149182.549347) vcan0 123#0801010101010101
(1585149182.550713) vcan0 123#0801010101010101
...
行长为46个字符,不包含换行符('\n'
)或47个字符,包括换行符。
fgets
需要附加尾随的NUL
字符('\0'
)以终止字符串。这就是为什么第一次调用将读取没有换行符的行,因为缓冲区已满。缓冲区将包含字符串
"(1585149182.549347) vcan0 123#0801010101010101"
下一个调用将仅读取换行符,因为这是该行的结尾。缓冲区将包含
"\n"
您必须将raw_message
的大小增加到至少48。然后你会得到
"(1585149182.549347) vcan0 123#0801010101010101\n"
一个fgets
通话中。
注意,最好使用socketcan interface读取二进制CAN消息,而不是解析candump
的文本输出。