Java 将big-endian转换为2字节数
以下是通过5字节数据中的套接字发送的参数:Java 将big-endian转换为2字节数,java,byte,endianness,Java,Byte,Endianness,以下是通过5字节数据中的套接字发送的参数: Parameters : methodname(1 byte), payloadlength(2 byte), payload(2 byte) methodName = 5 payload = 2151 我想用5字节发送以上三个数据。 最终发送字节为0500020867。如何获取最后的字节 int methodname = 5; int payload = 2151; ByteBuffer b = ByteBuffer.alloca
Parameters : methodname(1 byte), payloadlength(2 byte), payload(2 byte)
methodName = 5
payload = 2151
我想用5字节发送以上三个数据。
最终发送字节为0500020867。如何获取最后的字节
int methodname = 5;
int payload = 2151;
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(payload);
byte[] payloadData = b.array();
int payloadlength = payloadData.length;
byte[] result = new byte[5];
result[0] = (byte) (methodname);
result[1] = (byte) (payloadlength >> 8);
result[2] = (byte) (payloadlength);
result[3] = (byte) (payload >> 8);
result[4] = (byte) (payload);
for (int i = 0; i < 5; i++)
System.out.printf("%x\n", result[i]);
result: 5 0 4 8 67
//expected result: 05 00 02 08 67
有人能帮我吗。任何形式的帮助都是值得的。
谢谢
阿卡什爪哇是。无需对网络字节顺序执行转换
下面是一个示例程序来演示这一点。这主要是直接取自。从输出中可以看到,前两个字节为0,因此首先存储MSB
import java.util.*;
import java.nio.ByteBuffer;
public class Main{
public static void main(String[] args) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(2151);
byte[] result = b.array();
for (int i = 0; i < 4; i++)
System.out.printf("%x\n", result[i]);
}
}
更新:下面是我们如何使OP的更新问题起作用的
import java.util.*;
import java.nio.ByteBuffer;
public class Main{
public static byte[] getBytes(int input) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(input);
return b.array();
}
public static void main(String[] args) {
int methodname = 5;
int payload = 2151;
byte[] payloadBytes = getBytes(payload);
int payloadlength = 2; // We always assume this is 2.
byte[] result = new byte[5];
result[0] = (byte) (methodname);
// The following two lines are the same always.
result[1] = 0;
result[2] = (byte) (payloadlength);
// Here we put in the payload, ignoring the first two Most Significant Bytes
result[3] = payloadBytes[2];
result[4] = payloadBytes[3];
for (int i = 0; i < 5; i++)
System.out.printf("%x\n", result[i]);
}
}
Java是。无需对网络字节顺序执行转换
下面是一个示例程序来演示这一点。这主要是直接取自。从输出中可以看到,前两个字节为0,因此首先存储MSB
import java.util.*;
import java.nio.ByteBuffer;
public class Main{
public static void main(String[] args) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(2151);
byte[] result = b.array();
for (int i = 0; i < 4; i++)
System.out.printf("%x\n", result[i]);
}
}
更新:下面是我们如何使OP的更新问题起作用的
import java.util.*;
import java.nio.ByteBuffer;
public class Main{
public static byte[] getBytes(int input) {
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(input);
return b.array();
}
public static void main(String[] args) {
int methodname = 5;
int payload = 2151;
byte[] payloadBytes = getBytes(payload);
int payloadlength = 2; // We always assume this is 2.
byte[] result = new byte[5];
result[0] = (byte) (methodname);
// The following two lines are the same always.
result[1] = 0;
result[2] = (byte) (payloadlength);
// Here we put in the payload, ignoring the first two Most Significant Bytes
result[3] = payloadBytes[2];
result[4] = payloadBytes[3];
for (int i = 0; i < 5; i++)
System.out.printf("%x\n", result[i]);
}
}
扔掉它,使用DataOutputStream.writeInt,或者,如果需要2个字节,使用writeShort
注意,您的方法SHORT_little_endian_TO_big_endian的名称有误,因为它所做的与输入的endian无关,输入的endian只需符合平台的本机顺序即可。在C语言中,它可以在little-endian和big-endian硬件上工作。扔掉它,使用DataOutputStream.writeInt,或者,如果需要2个字节,使用writeShort
注意,您的方法SHORT_little_endian_TO_big_endian的名称有误,因为它所做的与输入的endian无关,输入的endian只需符合平台的本机顺序即可。在C语言中,它可以在little-endian和big-endian硬件上工作。您正在使用的ByteBuffer类具有设置endianness和将不同长度的值放入/获取到缓冲区的方法。我建议你用这个
比如:
int methodname = 5;
int payload = 2151;
int payloadLength = 2;
ByteBuffer buffer = ByteBuffer.allocate(3 + payloadLength); // 3 = for method name + length
buffer.order(ByteOrder.BIG_ENDIAN); // Just to be explicit
buffer.put((byte) methodname);
buffer.putShort((short) payloadLength);
buffer.putShort((short) payload);
buffer.rewind();
byte[] result = new byte[buffer.capacity()]; // Could also use result = buffer.array();
buffer.get(result);
for (int i = 0; i < result.length; i++) {
System.out.printf("%02x ", result[i]);
}
正如所料
PS:原始代码中的问题是:
ByteBuffer b = ByteBuffer.allocate(4); // Here you allocate buffer of size 4
// ...
byte[] payloadData = b.array(); // The array will always have size of buffer
int payloadlength = payloadData.length; // ...meaning pD.length will always be 4
您已经使用的ByteBuffer类具有设置endianness的方法,以及将/获取不同长度的值放入缓冲区的方法。我建议你用这个
比如:
int methodname = 5;
int payload = 2151;
int payloadLength = 2;
ByteBuffer buffer = ByteBuffer.allocate(3 + payloadLength); // 3 = for method name + length
buffer.order(ByteOrder.BIG_ENDIAN); // Just to be explicit
buffer.put((byte) methodname);
buffer.putShort((short) payloadLength);
buffer.putShort((short) payload);
buffer.rewind();
byte[] result = new byte[buffer.capacity()]; // Could also use result = buffer.array();
buffer.get(result);
for (int i = 0; i < result.length; i++) {
System.out.printf("%02x ", result[i]);
}
正如所料
PS:原始代码中的问题是:
ByteBuffer b = ByteBuffer.allocate(4); // Here you allocate buffer of size 4
// ...
byte[] payloadData = b.array(); // The array will always have size of buffer
int payloadlength = payloadData.length; // ...meaning pD.length will always be 4
我觉得这可能会有帮助。谢谢@EdwinDalorzo的回复,但是我在线程主java.nio.BufferUnderflowException中得到了异常,在java.nio.Buffer.nextgetGetIndexUnknown Source中得到了异常,在java.nio.HeapByteBuffer.getIntUnknown Source中得到了整个堆栈跟踪吗?一个int是4字节。您只在ByteBuffer中添加了2个。另外,0867的值来自何处?我觉得这可能会有所帮助。感谢您的回复,但是我在主线程java.nio.BufferUnderflowException中得到异常,位于java.nio.Buffer.nextGetIndexUnknown源java.nio.HeapByteBuffer.getIntUnknown源是整个堆栈跟踪吗?int是4字节。您只向ByteBuffer中添加了2。另外,值0867从何而来?我只能以2字节格式发送请求数据,因此请建议我必须做的事情。@AkashG:使用ByteBuffer.putShort而不是ByteBuffer.putInt。@merlin2011:Java已经是big-Endian不是真的。您的解决方案之所以有效,是因为ByteBuffer明确支持字节顺序,并且最初处于Big-Endian模式。@Codo,此外,字节码指令中的操作数如果跨越多个字节,也是Big-Endian。您是否建议将变量存储在JVM中的little Endian中,字节码操作数是big Endian?@Codo,您的逻辑是有道理的,但我非常希望有一些文档描述在类加载期间将变量转换为本机字节顺序的过程,以及JVM本机字节顺序的变量存储。我只能以2字节格式发送请求数据,因此请建议我必须做的事情。@AkashG:使用ByteBuffer.putShort而不是ByteBuffer.putInt。@merlin2011:Java已经是big-Endian不是真的。您的解决方案之所以有效,是因为ByteBuffer明确支持字节顺序,并且最初处于Big-Endian模式。@Codo,此外,字节码指令中的操作数如果跨越多个字节,也是Big-Endian。您是否建议将变量存储在JVM中的little Endian中,字节码操作数是big Endian?@Codo,您的逻辑是有道理的,但我非常希望有一些文档描述在类加载期间将变量转换为本机字节顺序的过程,以及JVM的本机字节顺序的变量存储。我已经编辑了我的问题,并尝试了另一种方法。你能建议得到想要的结果吗?@AkashG我已经建议了一种得到想要的结果的方法。如果你想要另一种方式,你需要说明原因,以及这种方式有什么不令人满意的地方。我已经编辑了我的问题,并尝试了另一种方式。你能建议得到想要的结果吗?@AkashG我已经建议了一种得到想要的结果的方法。如果你 你需要用另一种方式说明原因,以及这种方式有什么不令人满意的地方。