一段Java代码驻留在服务器上,该服务器需要来自一块硬件的大约64字节信息,通过TCP发送。该数据包有一个10字节的标头。第一个字节是协议标识符,后两个字节给出数据包中的总字节数,包括所有头字节和校验和。最后7个字节是UID。
服务器代码:
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(data)是否正确转储接收到的缓冲区,我知道该缓冲区应该是可读的HEX字符串?
注意:此问题的根源在于:Java TCP Socket Byte Heap Memory Issue
答案 0 :(得分:2)
如果对方使用DataInputStream
或其格式正确,则仅使用DataOutputStream
。例如,整数可以编码big-endian or little-endian - DataOutputStream
使用big-endian表示法,如果另一方使用不同的编码,则不能使用DataInputStream
。如果需要,使用InputStream.read()
可以为您提供更多控制。
现在,由于您所声明的消息格式以协议标识符的一个字节开头,因此您首先需要将其作为字节(dis.readByte()
或InputStream.read()
)读取,并检查协议是否为你期望或处理不同的协议。然后你阅读消息长度等。
答案 1 :(得分:0)
您可以使用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
但我建议您使用InputStream.read()
代替DateInputStream