byte到int类型转换网络应用
byte to int type conversion network application
我从我的 android phone 整数发送带有以下代码的字节(我只放了需要的块):
private byte[] intToByteArray ( final int i ) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(i);
dos.flush();
return bos.toByteArray();
}
//thread sender
data = new byte[16];
...
try {
temp = intToByteArray((int) (roll*100));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
data[3] = temp[0];
data[4] = temp[1];
data[5] = temp[2];
data[6] = temp[3];
...
p = new DatagramPacket(data, 16);
udpSocket.send(p);
发送代码有效,因为我已经用收到的 Java 试过了,结果是正确的。真正的接收器必须使用嵌入式设备 Murata SN8200 来实现:我收到了数据包,但我的整数结果(例如,roll)不正确。我用于从 byte 转换为 int 的代码如下:
void getSubArray(char* dest, char* source, int start, int end){
uint8_t i, j = 0;
for(i=start; i<end; i++){
dest[j] = source[i];
j++;
}
}
int byteToInt(char* bytes)
{
int ch1 = bytes[0];
int ch2 = bytes[1];
int ch3 = bytes[2];
int ch4 = bytes[3];
if ((ch1 | ch2 | ch3 | ch4) < 0)
WPRINT_APP_INFO ( ("boh\r\n"));
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
...
//thread receiver
wiced_packet_get_data(packet, 0, (uint8_t**)&rx_data, &rx_data_length, &available_data_length);
traffic_type = rx_data[0];
id = rx_data[1];
takeOffPressed = rx_data[2];
getSubArray(temp, rx_data, 3, 7);
roll = byteToInt(temp);
WPRINT_APP_INFO ( ("Rx: \" Packet Type: %c Id: %c TakeOffPressed = %c \r\n roll: %d \r\n ", (unsigned char )traffic_type, (unsigned char )id, (unsigned char)takeOffPressed, roll);
阅读我已经尝试过的其他讨论:roll = (int*)(temp);正如另一个 post 中所建议的那样,但它对我不起作用(别名编译器错误)。有解决问题的想法吗?谢谢
#include <sdint.h>
#include <string.h>
#include <netinet/in.h>
uint32_t byteToInt(char* bytes)
{
uint8_t b[4];
memcpy(b, bytes, 4);
if ((b[0] | b[1] | b[2] | b[3]) < 0)WPRINT_APP_INFO ( ("boh\r\n"));
return ntohl(*((uint32_t *)b));
}
...
//thread receiver
wiced_packet_get_data(packet, 0, (uint8_t**)&rx_data, &rx_data_length, &available_data_length);
traffic_type = rx_data[0];
id = rx_data[1];
takeOffPressed = rx_data[2];
memcpy(temp, rx_data+3, 4);
roll = byteToInt(temp);
WPRINT_APP_INFO ( ("Rx: \" Packet Type: %c Id: %c TakeOffPressed = %c \r\n roll: %d \r\n ", (unsigned char )traffic_type, (unsigned char )id, (unsigned char)takeOffPressed, roll);
不需要
void getSubArray(char* dest, char* source, int start, int end)
你可以用
代替
memcpy(void* dest, void* src, size_t t);//from string.h
此外,我已经将您的 byteToInt 函数修改为更有趣的东西
您可能有一些符号混淆。考虑您的 byteToInt()
函数:
int byteToInt(char* bytes)
{
int ch1 = bytes[0];
int ch2 = bytes[1];
int ch3 = bytes[2];
int ch4 = bytes[3];
if ((ch1 | ch2 | ch3 | ch4) < 0)
WPRINT_APP_INFO ( ("boh\r\n"));
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
假设发送的 4 字节值是 511
(十进制)。发送的字节为 0x00 0x00 0x01 0xff
。现在假设接收系统具有带符号的二进制补码 char
s,这并不罕见。在这种情况下,在接收器上,这些字符将被解释为值 0 0 1 -1
(十进制)。现在有两个问题:
- 将移位运算符应用于左负操作数(即我示例中
ch4
的值)的行为未定义。
-1 << 0
的一个合理可能的实际行为是产生 -1
(计算其左操作数值的零位移位)。在这种情况下,总计算值将是 256 + -1 = 255
.
当然,这只是一个例子,但是16个32位int
中只有一个每个字节的高位被清除。
这两个问题都可以通过使用适当的无符号量执行计算来解决。可以这样做:
int byteToInt(char* bytes)
{
uint8_t ch1 = bytes[0];
uint8_t ch2 = bytes[1];
uint8_t ch3 = bytes[2];
uint8_t ch4 = bytes[3];
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
还要注意,提取子数组传递给 byteToInt()
是一种浪费。最好只使用一点指针运算:
roll = byteToInt(rx_data + 3);
我从我的 android phone 整数发送带有以下代码的字节(我只放了需要的块):
private byte[] intToByteArray ( final int i ) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(i);
dos.flush();
return bos.toByteArray();
}
//thread sender
data = new byte[16];
...
try {
temp = intToByteArray((int) (roll*100));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
data[3] = temp[0];
data[4] = temp[1];
data[5] = temp[2];
data[6] = temp[3];
...
p = new DatagramPacket(data, 16);
udpSocket.send(p);
发送代码有效,因为我已经用收到的 Java 试过了,结果是正确的。真正的接收器必须使用嵌入式设备 Murata SN8200 来实现:我收到了数据包,但我的整数结果(例如,roll)不正确。我用于从 byte 转换为 int 的代码如下:
void getSubArray(char* dest, char* source, int start, int end){
uint8_t i, j = 0;
for(i=start; i<end; i++){
dest[j] = source[i];
j++;
}
}
int byteToInt(char* bytes)
{
int ch1 = bytes[0];
int ch2 = bytes[1];
int ch3 = bytes[2];
int ch4 = bytes[3];
if ((ch1 | ch2 | ch3 | ch4) < 0)
WPRINT_APP_INFO ( ("boh\r\n"));
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
...
//thread receiver
wiced_packet_get_data(packet, 0, (uint8_t**)&rx_data, &rx_data_length, &available_data_length);
traffic_type = rx_data[0];
id = rx_data[1];
takeOffPressed = rx_data[2];
getSubArray(temp, rx_data, 3, 7);
roll = byteToInt(temp);
WPRINT_APP_INFO ( ("Rx: \" Packet Type: %c Id: %c TakeOffPressed = %c \r\n roll: %d \r\n ", (unsigned char )traffic_type, (unsigned char )id, (unsigned char)takeOffPressed, roll);
阅读我已经尝试过的其他讨论:roll = (int*)(temp);正如另一个 post 中所建议的那样,但它对我不起作用(别名编译器错误)。有解决问题的想法吗?谢谢
#include <sdint.h>
#include <string.h>
#include <netinet/in.h>
uint32_t byteToInt(char* bytes)
{
uint8_t b[4];
memcpy(b, bytes, 4);
if ((b[0] | b[1] | b[2] | b[3]) < 0)WPRINT_APP_INFO ( ("boh\r\n"));
return ntohl(*((uint32_t *)b));
}
...
//thread receiver
wiced_packet_get_data(packet, 0, (uint8_t**)&rx_data, &rx_data_length, &available_data_length);
traffic_type = rx_data[0];
id = rx_data[1];
takeOffPressed = rx_data[2];
memcpy(temp, rx_data+3, 4);
roll = byteToInt(temp);
WPRINT_APP_INFO ( ("Rx: \" Packet Type: %c Id: %c TakeOffPressed = %c \r\n roll: %d \r\n ", (unsigned char )traffic_type, (unsigned char )id, (unsigned char)takeOffPressed, roll);
不需要
void getSubArray(char* dest, char* source, int start, int end)
你可以用
代替memcpy(void* dest, void* src, size_t t);//from string.h
此外,我已经将您的 byteToInt 函数修改为更有趣的东西
您可能有一些符号混淆。考虑您的 byteToInt()
函数:
int byteToInt(char* bytes)
{
int ch1 = bytes[0];
int ch2 = bytes[1];
int ch3 = bytes[2];
int ch4 = bytes[3];
if ((ch1 | ch2 | ch3 | ch4) < 0)
WPRINT_APP_INFO ( ("boh\r\n"));
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
假设发送的 4 字节值是 511
(十进制)。发送的字节为 0x00 0x00 0x01 0xff
。现在假设接收系统具有带符号的二进制补码 char
s,这并不罕见。在这种情况下,在接收器上,这些字符将被解释为值 0 0 1 -1
(十进制)。现在有两个问题:
- 将移位运算符应用于左负操作数(即我示例中
ch4
的值)的行为未定义。 -1 << 0
的一个合理可能的实际行为是产生-1
(计算其左操作数值的零位移位)。在这种情况下,总计算值将是256 + -1 = 255
.
当然,这只是一个例子,但是16个32位int
中只有一个每个字节的高位被清除。
这两个问题都可以通过使用适当的无符号量执行计算来解决。可以这样做:
int byteToInt(char* bytes)
{
uint8_t ch1 = bytes[0];
uint8_t ch2 = bytes[1];
uint8_t ch3 = bytes[2];
uint8_t ch4 = bytes[3];
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
}
还要注意,提取子数组传递给 byteToInt()
是一种浪费。最好只使用一点指针运算:
roll = byteToInt(rx_data + 3);