从数据包头设置Java字节数组大小
一段Java代码驻留在一台服务器上,期望从一块硬件通过TCP发送大约64字节的信息。数据包有一个10字节的报头。第一个字节是协议标识符,第二个两个字节给出数据包中的总字节数,包括所有头字节和校验和。最后7个字节是UID 服务器代码:从数据包头设置Java字节数组大小,java,sockets,tcp,bytearray,Java,Sockets,Tcp,Bytearray,一段Java代码驻留在一台服务器上,期望从一块硬件通过TCP发送大约64字节的信息。数据包有一个10字节的报头。第一个字节是协议标识符,第二个两个字节给出数据包中的总字节数,包括所有头字节和校验和。最后7个字节是UID 服务器代码: public void run () throws Exception { //Open a socket on localhost at port 11111 ServerSocket welcomeSocket = ne
public void run () throws Exception
{
//Open a socket on localhost at port 11111
ServerSocket welcomeSocket = new ServerSocket(11111);
while(true) {
//Open and Accept on Socket
Socket connectionSocket = welcomeSocket.accept();
//Alt Method
DataInputStream dis = new DataInputStream(connectionSocket.getInputStream());
int len = dis.readInt();
byte[] data = new byte[len];
if (len > 0) {
dis.readFully(data);
}
System.out.println("Recv[HEX]: " + StringTools.toHexString(data));
}
}
问题是我的readInt()行,它占用前四个字节,但是我需要根据后两个字节确定长度。如何做到这一点
第二,我的stringTools.toHexString(数据)是否正确,以转储我知道应该作为十六进制字符串读取的接收缓冲区
注意:这个问题的根源在这里:如果另一方使用的是
DataOutputStream
或其确切格式,则仅使用DataInputStream
。例如,整数可以被编码-DataOutputStream
使用大端符号,如果另一端使用不同的编码,则不能使用DataInputStream
。如果需要,使用InputStream.read()
可以提供更多的控制
现在,由于您所述的消息格式以协议标识符的一个字节开始,因此您首先需要将其作为一个字节读取(
dis.readByte()
或InputStream.read()
),并检查协议是否符合您的预期或处理不同的协议。然后读取消息长度等。您可以使用ByteBuffer
读取最后两个字节中的int
import static java.lang.System.out;
import java.nio.ByteBuffer;
class B {
public static void main( String ... args ) {
// test value
int a = 1238098;
// convert it into an arrays of bytes
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(a);
byte [] r = b.array();
// read last two
int size = ByteBuffer.wrap(new byte[]{0x0,0x0, r[2], r[3]}).getInt();
// print it
out.println("Original: " + String.format("%32s%n" , Integer.toString(a,2)).replace(' ', '0'));
out.printf("Last two: %32s%n" , Integer.toString(size,2));
out.printf("Decimal : %d%n" , size );
}
}
输出:
Original: 00000000000100101110010001010010
Last two: 1110010001010010
Decimal : 58450
不过,我建议您按照@Jiri的回答,使用
InputStream.read()
而不是DateInputStream
阅读,谢谢Jira。传入的格式是Big-Endian。我知道如何读取第一个字节,如何读取下两个字节来确定我的字节数组必须有多大?如果下两位是大端编码的整数,您可以在处理第一个字节后对其使用dis.readInt()
。根据您的说法,它包含数据包的总长度,因此您必须对其他字段的长度进行细分才能获得有效负载长度。