从套接字的byte []开始解析int(Parsing int from the start of a byte[] from a socket)

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

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

每条消息前面都有消息大小指示符,它是一个使用网络字节顺序方法的32位无符号整数。 例如:\ x05 \ 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);

I have a Java application that is reading data from a TCP socket that is receiving XML of varying size. The first 5 bytes of a given packet are supposed to indicate the size of the remaining message. I can read the message and xml successfully if I manually create a large byte[] and read the data.

Here are the instructions from the manual for the application that is generating the data:

Each message is preceded by the message size indicator which is a 32-bit unsinged integer using the network bytes order method. For example: \x05\x00\x00\x00\x30\x31\x30\x32\x00 indicates the message size of an ack which is 5 bytes included the fifth message byte '\0'. The size indicator specifies everything following the size indicator itself.

However I can't figure out how to decode the first 5 bytes to an integer that I can use to correctly size a byte[] for reading the rest of the message. I get random results:

Here is the code I'm using to parse the message:

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);

最满意答案

长度看起来像是小尾巴。 您仍然可以使用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);

The length looks like it's little endian. You can still use DataInputStream but you have to swap the bytes. If you used NIO's SocketChannel and a ByteBuffer you could set the byte order, but this is likely to be harder to use.

// 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);

更多推荐