简体   繁体   English

Java-从套接字通道读取

[英]Java - Reading from a socketchannel

So I am using SocketChannels in java to send and receive data for a project. 所以我在Java中使用SocketChannels发送和接收项目的数据。 The project interacts with a 3rd party who require a ByteBuffer of the data but which is prefixed with 4 bytes which is its length. 该项目与需要数据ByteBuffer的第3方进行交互,但其前缀为4个字节(即其长度)。

When receiving I will receive a ByteBuffer which I need to deconstruct the 4 byte length from the front and extract the data. 接收时,我将收到一个ByteBuffer,它需要从前面解构4字节的长度并提取数据。 The messages I receive are not fixed length. 我收到的消息长度不固定。

My current implementation is as follows: 我当前的实现如下:

public PedResponse send(ByteBuffer message) {
        String returnString;
        try {

            message.flip();

            while (message.hasRemaining()) {
                socketChannel.write(message);
            }

            ByteBuffer readBuffer = ByteBuffer.allocate(5000);
            int bufferSize = socketChannel.read(readBuffer);
            if (bufferSize == -1) {
                socketChannel.close();
            } else {
                readBuffer.flip();
            }

            returnString = new String(deconstructMessage(readBuffer.array()), "UTF-8").trim();

            response = parser.parseResponse(returnString);

        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

private ByteBuffer constructMessage(byte[] data) {

        // Construct a buffer where we'll put the data to send
        ByteBuffer sendBuffer = ByteBuffer.allocate(4 + data.length);

        // it's the default, but included for clarity
        sendBuffer.order(ByteOrder.BIG_ENDIAN);

        // Put the 4-byte length, then the data
        sendBuffer.putInt(data.length);
        sendBuffer.put(data);

        // Extract the actual bytes from our sendBuffer
        return sendBuffer;
    } 

public byte[] deconstructMessage(byte[] data) {

        byte[] filteredByteArray = Arrays.copyOfRange(data, 4, data.length - 4);

        return filteredByteArray;
    }

//Currently not being used.
private byte[] deconstructMessage(byte[] data) {

        // Construct a buffer where we'll put the data to send
        ByteBuffer receiveBuffer = ByteBuffer.allocate(data.length);

        // it's the default, but included for clarity
        receiveBuffer.order(ByteOrder.BIG_ENDIAN);

        // Get the 4-byte length, then the data
        receiveBuffer.getInt(data.length);
        receiveBuffer.get(data);

        // Extract the actual bytes from our receivedBuffer
        byte[] dataReceived = receiveBuffer.array();
        return dataReceived;
    }

So as you can see, I am creating a new ByteBuffer with the size of 5000, but ideally I don't want to do this. 如您所见,我正在创建一个大小为5000的新ByteBuffer,但理想情况下,我不想这样做。 So the question I have, is how can I not use this oversized ByteBuffer, but instead just read the data I received, so I can use my unused deconstruct message method? 因此,我的问题是,如何不能使用这个过大的ByteBuffer,而只是读取我收到的数据,以便可以使用未使用的deconstruct消息方法?

ByteBuffer has method get() and it returns byte from the current position. ByteBuffer具有方法get() ,它从当前位置返回字节。 So, you can read 4 bytes first and get the size. 因此,您可以先读取4个字节并获取大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM