Java 无符号短到字节数组

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

我必须将一个短消息作为未签名短消息发送到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 (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