Java 从套接字的字节[]开始解析int

Java 从套接字的字节[]开始解析int,java,sockets,tcp,bytearray,Java,Sockets,Tcp,Bytearray,我有一个Java应用程序,它从接收不同大小XML的TCP套接字读取数据。给定数据包的前5个字节应表示剩余消息的大小。如果手动创建一个大字节[]并读取数据,则可以成功读取消息和xml 以下是生成数据的应用程序手册中的说明: 每条消息前面都有消息大小指示符,该指示符是 使用网络字节顺序方法的32位无符号整数。对于 示例:\x05\x00\x00\x00\x00\x30\x31\x30\x32\x00表示消息 ack的大小为5字节,包括第五个消息字节“\0”。这个 尺寸指示器指定尺寸指示器后面的所有内

我有一个Java应用程序,它从接收不同大小XML的TCP套接字读取数据。给定数据包的前5个字节应表示剩余消息的大小。如果手动创建一个大字节[]并读取数据,则可以成功读取消息和xml

以下是生成数据的应用程序手册中的说明:

每条消息前面都有消息大小指示符,该指示符是 使用网络字节顺序方法的32位无符号整数。对于 示例:\x05\x00\x00\x00\x00\x30\x31\x30\x32\x00表示消息 ack的大小为5字节,包括第五个消息字节“\0”。这个 尺寸指示器指定尺寸指示器后面的所有内容 本身

但是,我不知道如何将前5个字节解码为一个整数,以便正确调整字节[]的大小以读取消息的其余部分。我得到随机结果:

下面是我用来解析消息的代码:

DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
BufferedInputStream inFromServer = new BufferedInputStream(clientSocket.getInputStream());

byte[] data = new byte[10];
inFromServer.read(data);
String result = new String(data, "ISO-8859-1");

Logger.info(data+"");

//PROBLEM AREA: Tried reading different byte lengths but no joy
//This should be a number but it never is. Often strange symbols
byte[] numeric = Arrays.copyOfRange(data,1,5);
String numericString = new String(numeric, "ISO-8859-1");

//Create a huge array to make sure everything gets captured. 
//Want to use the parsed value from the start here
byte[] message = new byte[1000000];
inFromServer.read(message);

//This works as expected and returns correctly formatted XML
String fullMessage = new String(message, "ISO-8859-1");

Logger.info("Result "+result+ " Full message "+fullMessage);

长度看起来像是小endian。您仍然可以使用DataInputStream,但必须交换字节。如果使用NIO的SocketChannel和ByteBuffer,您可以设置字节顺序,但这可能更难使用

// only do this once per socket.
DataInputStream in = new DataInputStream(
                                  new BufferedInputStream(clientSocket.getInputStream()));

// for each message.
int len0 = in.readInt();
int len = Integer.reverseBytes(len0);
assert len < 1 << 24;

byte[] bytes = new byte[len];
in.readFully(bytes);

String text = new String(bytes, "ISO-8859-1").trim();
int number = Integer.parseInt(text);
//每个套接字只执行一次。
DataInputStream in=新的DataInputStream(
新的BufferedInputStream(clientSocket.getInputStream());
//对于每条消息。
int len0=in.readInt();
int len=整数。反向字节(len0);

断言len<1长度看起来像是小endian。您仍然可以使用DataInputStream,但必须交换字节。如果使用NIO的SocketChannel和ByteBuffer,您可以设置字节顺序,但这可能更难使用

// only do this once per socket.
DataInputStream in = new DataInputStream(
                                  new BufferedInputStream(clientSocket.getInputStream()));

// for each message.
int len0 = in.readInt();
int len = Integer.reverseBytes(len0);
assert len < 1 << 24;

byte[] bytes = new byte[len];
in.readFully(bytes);

String text = new String(bytes, "ISO-8859-1").trim();
int number = Integer.parseInt(text);
//每个套接字只执行一次。
DataInputStream in=新的DataInputStream(
新的BufferedInputStream(clientSocket.getInputStream());
//对于每条消息。
int len0=in.readInt();
int len=整数。反向字节(len0);
断言len<1网络字节顺序为aka。但从你的数据看来,实际上使用的是little endian。至少
5
将看起来像小端字节中的前4个字节,但不是大端字节。因此,你需要读取那些字节,考虑小字节,并转换成长来考虑“无符号性”。 网络字节顺序是aka。但从你的数据看来,实际上使用的是little endian。至少
5
将看起来像小端字节中的前4个字节,但不是大端字节。因此,你需要读取那些字节,考虑小字节,并转换成长来考虑“无符号性”。
消息长度位于前四个而非五个字节的测试中,“网络字节顺序”看起来很像little endian,也称为非网络字节顺序。指令不正确。这不是网络字节顺序中的5。如果是,您可以使用
DataInputStream.readInt()
。事实上,您应该向供应商投诉(“寻求澄清”)。这不是XML。消息长度在前四个而不是五个字节的测试中,“网络字节顺序”看起来很像little endian,也称为非网络字节顺序。指令不正确。这不是网络字节顺序中的5。如果是,您可以使用
DataInputStream.readInt()
。事实上,您应该向供应商投诉(“寻求澄清”)。这不是XML。“网络字节顺序”在RFC中定义为big-endian。“网络字节顺序”在RFC中定义为big-endian。这是正确的,因为它与问题中发布的文档相关。然而,它却从另一方面证明了文档是错误的。文档中的示例是小尾端,但数据是大尾端。@JoeW在这种情况下,您可以删除
reverseBytes
这是正确的,因为它与问题中发布的文档相关。然而,它却从另一方面证明了文档是错误的。示例是文档中的小尾数,但数据是以大尾数形式出现的。@jow在这种情况下,您可以删除
reverseBytes