Java 无符号短到字节数组
我必须将一个短消息作为未签名短消息发送到TCPServer 问题是Java不支持usigned Short: 我所尝试的:Java 无符号短到字节数组,java,c++,byte,short,Java,C++,Byte,Short,我必须将一个短消息作为未签名短消息发送到TCPServer 问题是Java不支持usigned Short: 我所尝试的: byte[] data = new byte[3]; short port = 5025; data[0] = 1; data[1] = (byte)(port & 0xff); data[2] = (byte)((port >> 8) & 0xff); 这就是我如何将数据转换成C中的无符号短字符的方法++ // Bytes to Short
byte[] data = new byte[3];
short port = 5025;
data[0] = 1;
data[1] = (byte)(port & 0xff);
data[2] = (byte)((port >> 8) & 0xff);
这就是我如何将数据转换成C中的无符号短字符的方法++
// Bytes to Short (uint16)
unsigned short port = (data[1] << 8) | data[2];
C++代码:(相同)
unsigned short port=(data[1]这无关紧要。只需将它放在short
中即可。有符号的short
无关紧要;short
仍然是16位
重要的是这里的endian。如果你通过网络发送,它是big endian
这是ByteBuffer的默认值,也是Java的所有数值原语类型的默认值
那么,你是怎么做的?对于你的特定示例,如下所示:
// Just for a short...
final ByteBuffer buf = ByteBuffer.allocate(3);
buf.put((byte) 1);
buf.putShort(myShort);
final byte[] contents = buf.array();
// send the byte[]
现在,如果您有更多的内容要。请将*()
放入字节缓冲区
,分配所需的空间等
但是,你说你不想改变任何C++代码……它不是跨架构的。如果你想在C++中通过网络读取/写入16位值,请使用<代码> ntoh()/HutsSh()/<代码> < /P>
(也许还有比这更好的API;我已经有一段时间没有在C/C++中完成高级网络编程了) 我有一个稍微不同的观点。OP使用正确的位转换来进入小端字节,所以C++的移植性会很好,除非他处理一个非常规的字节。通信协议违背了网络约定的大字节,但有时支持遗留系统是这样的。
如果端口变量的用户不在提供的代码中,请使用int并只发送您想要的位,就像您在上面的Java示例中所做的那样。如果您要传递该端口,那么继续旋转该死的符号位很糟糕,迟早您会把它搞砸。如果没有其他人需要使用端口,则符号无关紧要
byte[] data = new byte[3];
int port = 5025; // short or int doesn't matter in this case
data[0] = 1;
data[1] = (byte)(port & 0xff);
data[2] = (byte)((port >> 8) & 0xff);
当读回并得到65440时,看起来您使用了一个字符,并且您的字节通过移位得到了符号扩展
#include <cstdio>
int main()
{
unsigned short val = 32896;
char hi = (char)((val >> 8) & 0xFF);
char lo = (char)(val &0xFF);
printf("Watch what the sign bit can do to the bytes here:\n");
printf("Value: %d, raw in hex: %04x, Hi byte: %02x, Low byte: %02x\n", val, val, hi, lo);
printf("This one only works if the low byte doesn't sign extend\n");
char datas[3] = {0, hi, lo};
unsigned short port = (datas[1] << 8) | datas[2];
printf("Reassembled short: %u, In Hex: %04x\n", port, port);
printf("This one works, but will not for an integer\n");
port = (datas[1] << 8) | (datas[2] & 0xFF);
printf("Reassembled short: %u, in Hex: %04x\n", port, port);
unsigned int bigport = (datas[1] << 8) | (datas[2] & 0xFF);
printf("Reassembled int: %u, in Hex: %04x\n", bigport, bigport);
printf("With unsigned characters it just works\n");
unsigned char datau[3] = {0, hi, lo};
port = (datau[1] << 8) | datau[2];
printf("Reassembled short: %u, In Hex: %04x\n", port, port);
bigport = (datau[1] << 8) | (datau[2] & 0xFF);
printf("Reassembled int: %u, in Hex: %04x\n", bigport, bigport);
}
发生了什么事
(datas[1] << 8) | datas[2]
这是我的荣幸
0xFF80
又名65408,不是32896
C++ C++中的一个例子,是:“没有符号的字符是你的朋友。”Java可能有问题,但是C++确实是坏了。< /p>再次阅读我的答案。特别是C++部分。但是我不想改变C++中的任何东西,因为另一个C++写的客户端也在连接。是的,你保证所有C++客户端都使用CPU圆弧。你的C++程序对于不同的顺序结构来说是行不通的。但是,同样,java没有未签名的原始数值类型的问题在这里并不是问题,你的问题是字节数。尝试改变字节缓冲区的字节数(小提示):提示:方法),但这样做基本上打破了所有事物联网的基本规则,即所有联网数据都必须以big-endian格式发送/接收。ntoh*/hton*()
系列并不是出于一时兴起而定义的。是的,我肯定。在我想使用它的PC上,它可以工作。:)但是我必须找到一个java解决方案谢谢!。但我只收到端口40975。如果我在C++中打印数据[1 ]和数据[2 ],我得到如下:<代码> FFFFFF A1 13 < /C> > C++中的数据数组是一种字符类型。这就是问题所在吗?我已经将数组的typ更改为unsigned char,但是没有区别,如果我在java中将字节设置为0xa0和0x0f,一切正常。因此,java java代码中的错误是告诉你做什么,@ FGE一直在问,编辑你的问题,包括更多或全部的Java输出例程和C++输入例程。没有这些,我们只能在黑暗中拍摄。您是否考虑过使用Wireshark或类似工具查看数据包的内容,以了解真正发送的是什么?您需要知道数字是如何工作的。1151=0x047f。将其拆分为两个字节04和7f。两者都是正数。1152=0x0480。04和80。80是负数(-128),char是有符号变量,因此如果调整大小,负数将被保留<代码>数据[1]
Watch what the sign bit can do to the bytes here:
Value: 32896, raw in hex: 8080, Hi byte: ffffff80, Low byte: ffffff80
This one only works if the low byte doesn't sign extend
Reassembled short: 65408, In Hex: ff80
This one works, but will not for an integer
Reassembled short: 32896, in Hex: 8080
Reassembled int: 4294934656, in Hex: ffff8080
This one just works
Reassembled short: 32896, In Hex: 8080
Reassembled int: 32896, in Hex: 8080
(datas[1] << 8) | datas[2]
(0xFF80 << 8) | 0xFF80
0x8000 | 0xFF80
0xFF80