Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从数据包头设置Java字节数组大小_Java_Sockets_Tcp_Bytearray - Fatal编程技术网

从数据包头设置Java字节数组大小

从数据包头设置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

一段Java代码驻留在一台服务器上,期望从一块硬件通过TCP发送大约64字节的信息。数据包有一个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(数据)是否正确,以转储我知道应该作为十六进制字符串读取的接收缓冲区


注意:这个问题的根源在这里:

如果另一方使用的是
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()
。根据您的说法,它包含数据包的总长度,因此您必须对其他字段的长度进行细分才能获得有效负载长度。