ByteBuffer не заполнен правильными данными - PullRequest
1 голос
/ 14 июля 2020

недавно я перешел с многопоточных сокетов на сокеты NIO. К сожалению, мне трудно преобразовать необработанные пакетные данные в ByteBuffer (или что-то похожее на него)

Итак, у вас есть два выхода, один из результирующего пакета и результирующее содержимое ByteBuffer, которое следует отправить.

SEND [0xfa2] 00 00 00 00 A2 0F 02 00 FE FF // the packet that should be sent
SEND [0xfa2] 00 00 00 00 A2 0F 02 00 00 00 // ByteBuffer content that is sent

Как видите, последние два байта в этом примере обнулены. И я не знаю почему. Данные содержат объект типа char (-2). (data.write((char) -2));)

Вот код того, как я помещаю данные в ByteBuffer:

public int send(Connection connection, Packet packet) throws IOException {

    SocketChannel socketChannel = this.socketChannel;
    if(socketChannel == null)
        throw new SocketException("Connection is closed.");

    synchronized (writeLock) {

        writeBuffer = ByteBuffer.allocate(packet.getDataLength() + 8);
        writeBuffer.order(ByteOrder.LITTLE_ENDIAN);
        
        // checksum
        writeBuffer.putInt(0);
        // packet
        writeBuffer.putChar(packet.getPacketId());
        writeBuffer.putChar(packet.getDataLength());
        writeBuffer.put(packet.getData(), 8, packet.getDataLength());

        // print content of Packet
        System.out.println("SEND [" + String.format("0x%x", (int)packet.getPacketId()) + "] " + BitKit.toString(packet.getRawPacket(), 0, packet.getDataLength() + 8));
        // print content of ByteBuffer
        System.out.println("SEND [" + String.format("0x%x", (int)packet.getPacketId()) + "] " + BitKit.toString(writeBuffer.array(), 0, writeBuffer.array().length));
        
        if(!writeToSocket()) {

            selectionKey.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        } else {
            selectionKey.selector().wakeup();
        }

        lastWriteTime = System.currentTimeMillis();

        return packet.getDataLength();
    }
}

Метод writeToSocket () просто записывает буфер.

private boolean writeToSocket() throws IOException {

    SocketChannel socketChannel = this.socketChannel;
    if(socketChannel == null)
        throw new SocketException("Connection is closed.");

    ByteBuffer buffer = writeBuffer;
    buffer.flip();
    while(buffer.hasRemaining()) {

        if(socketChannel.write(buffer) == 0)
            break;
    }
    buffer.compact();

    return buffer.position() == 0;
}

Надеюсь, ты сможешь мне помочь! Заранее спасибо!

...