4

我有一个嵌入式设备,它以这种格式向我发送 UTC 日期(日期为 4 个字节):

 buffer.push_back((BYTE)(time_utc & 0x000000FF));
 buffer.push_back((BYTE)((time_utc & 0x0000FF00) >> 8));
 buffer.push_back((BYTE)((time_utc & 0x00FF0000) >> 16));
 buffer.push_back((BYTE)((time_utc & 0xFF000000) >> 24));

在服务器上,我接收字节并将它们存储在中socket_buf,从索引 0-3 开始并使用以下逻辑对其进行解码

mypkt.dateTime = ( ( socket_buf[0] << 24) +  
(socket_buf[1 ] << 16) +  socket_buf[2] << 8) + 
(socket_buf[3] << 0));

但我不确定是否正确解码,因为我得到的日期不正确。谁能建议我正确的解码方法?我正在使用 Linux 命令解码日期(16711840 是我通过解码得到的数字):

#date -d @16711840
4

3 回答 3

8

编写代码是小端- 它首先发送最低有效字节。

您的阅读代码需要大端序- 它采用第 0 个字节并将其左移 24 位。

请注意,在这两种情况下,代码都不依赖于本地机器的字节顺序 - 编写的代码独立于此,只是它们彼此不一致。

试试这个,而不是:

mypkt.dateTime = ((socket_buf[0] <<  0) +
                  (socket_buf[1] <<  8) + 
                  (socket_buf[2] << 16) +
                  ((uint32_t)socket_buf[3] << 24));

强制转换是必要的(但仅在最后一次移位时),因为0x80 - 0xff将转换为 asigned int并且未定义移位到符号位的位会发生什么(感谢@Lundin)

注意:16711840 不是“当前”Unix 纪元日期时间值,无论您使用哪种字节序来表示它。您可能在其他地方遇到其他问题。

于 2013-05-30T10:54:22.447 回答
0

由于socket_buf声明为 unsigned char,socket_buf[0] << 24因此是一个错误。

socket_buf[0]是 unsigned char 并将整数提升为int. 在这个特定系统上是 16 位还是 32 位都没有关系,因为无论如何程序都会崩溃。在这两种情况下,它最终都是一个有符号变量。您将左移一个有符号变量并将二进制变量移入符号位。然后你对此做加法。

编写解码的正确方法是:

mypkt.dateTime = ( ((uint32_t)socket_buf[0] << 24) |
                   ((uint32_t)socket_buf[1] << 16) |
                   ((uint32_t)socket_buf[2] <<  8) |
                   ((uint32_t)socket_buf[3] <<  0) );

此外,您似乎在编码和解码之间向后更改字节顺序。我不太明白这与字节序有什么关系,您的代码只是在buffersock_buf.

于 2013-05-30T11:51:59.510 回答
-3

你清除你的socket_buf了吗?

你确定你的电脑是大端序的吗?

另外,我给你一个建议:使用 or 运算符而不是 plus。

这可以为您节省更多时间。

mypkt.dateTime = (long) ( ( socket_buf[0] << 24) |  (socket_buf[1] << 16) |  socket_buf[2] << 8) | (socket_buf[3] << 0));
于 2013-05-30T10:47:05.007 回答