в этой строке появляется ошибка Exception in thread "main" java.nio.BufferUnderflowException
	at java.base/java.nio.HeapByteBuffer.get(HeapByteBuffer.java:183)
	at java.base/java.nio.ByteBuffer.get(ByteBuffer.java:826)
	at serverUtils.ConnectionManager.handleRead(ConnectionManager.java:117)
	at serverUtils.ConnectionManager.processQuery(ConnectionManager.java:41)
	at serverUtils.Console.start(Console.java:27)
	at Server.main(Server.java:10)
Это происходит при отправке файла со второго подключенного клиента, как это исправить?
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;

public class ConnectionManager {
    private static final String ACK_MESSAGE_PREFIX = "<%s>Ack";
    static final int BUFFER_SIZE = 1024 * 1024;

    ServerSocketChannel serverSocketChannel;
    int port;

    public ConnectionManager(int port) {
        this.port = port;
    }

    public void initialize() throws IOException {
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        System.out.println("Server started on port " + port);
        System.out.println("============ * ============");
    }

    public void registerSelector(Selector selector) throws ClosedChannelException {
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
    }

    public void processQuery(Selector selector, SelectionKey key) throws IOException {
        if (!key.isValid()) {
            return;
        }
        if (key.isAcceptable()) {
            acceptConnection(key, selector);
        } else if (key.isReadable()) {
            handleRead(key);
        }
    }

    private void acceptConnection(SelectionKey key, Selector selector) throws IOException {
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
        SocketChannel clientSocketChannel = serverSocketChannel.accept();
        clientSocketChannel.configureBlocking(false);
        // Attach new ConnectionContext instance to the selection key
        ConnectionContext context = new ConnectionContext();
        clientSocketChannel.register(selector, SelectionKey.OP_READ, context);

        System.out.println("Accepted connection from " + clientSocketChannel.getRemoteAddress());
    }

    private void handleRead(SelectionKey key) throws IOException {
        SocketChannel clientSocketChannel = (SocketChannel) key.channel();
        ConnectionContext connectionContext = (ConnectionContext) key.attachment();

        if (connectionContext == null) {
            connectionContext = new ConnectionContext();
            key.attach(connectionContext);
        }

        ByteBuffer buffer = connectionContext.buffer;
        int bytesRead = clientSocketChannel.read(buffer);

        if (bytesRead < 0) {
            System.out.println("Closed connection with " + clientSocketChannel.getRemoteAddress());
            clientSocketChannel.close();
            key.cancel();
            System.out.println("============ * ============");
            return;
        }

        buffer.flip();

        // handle file transmission
        if (connectionContext.fileStarted) {
            // check if we need more data to continue reading the file
            if (connectionContext.fileName != null && connectionContext.fileLength >= 0 &&
                    buffer.remaining() >= connectionContext.fileLength + Long.BYTES) {

                // read the file contents
                byte[] fileContent = new byte[connectionContext.fileLength];
                buffer.get(fileContent);

                // check the separator
                connectionContext.separator = buffer.getLong();
                if (connectionContext.separator != 0L) {
                    throw new RuntimeException("Invalid separator");
                }

                // save the file and send an acknowledgement
                saveFile(connectionContext.fileName, fileContent);
                sendAck(clientSocketChannel, connectionContext.fileName);

                // reset context for next file transfer
                connectionContext.fileStarted = false;
                connectionContext.fileCompleted = true;
                connectionContext.fileName = null;
                connectionContext.fileLength = -1;

                // handle any remaining data in buffer
                if (buffer.remaining() > 0) {
                    handleRead(key);
                    return;
                }
            }
        } else {
            // read the header of the file transfer
            while (buffer.hasRemaining() && !connectionContext.fileStarted) {
                // read the name length
                if (connectionContext.fileName == null && buffer.remaining() >= Integer.BYTES) {
                    int nameLength = buffer.getInt();
                    byte[] nameBytes = new byte[nameLength];
                    buffer.get(nameBytes);
                    connectionContext.fileName = new String(nameBytes, StandardCharsets.UTF_8);
                }

                // read the file length
                if (connectionContext.fileLength < 0 && buffer.remaining() >= Integer.BYTES) {
                    connectionContext.fileLength = buffer.getInt();
                    if (connectionContext.fileLength < 0) {
                        throw new RuntimeException("Invalid file length");
                    }
                    connectionContext.fileStarted = true;

                    // check if we need more data to continue reading the file
                    if (buffer.remaining() < BUFFER_SIZE) {
                        buffer.compact();
                        return;
                    }
                }
            }
        }

        // handle file transmission continued with remaining data in buffer
        if (connectionContext.fileStarted && !connectionContext.fileCompleted &&
                buffer.remaining() >= connectionContext.fileLength + Long.BYTES) {

            // read the file contents
            byte[] fileContent = new byte[connectionContext.fileLength];
            buffer.get(fileContent);

            // check the separator
            connectionContext.separator = buffer.getLong();
            if (connectionContext.separator != 0L) {
                throw new RuntimeException("Invalid separator");
            }

            // save the file and send an acknowledgement
            saveFile(connectionContext.fileName, fileContent);
            sendAck(clientSocketChannel, connectionContext.fileName);

            // reset context for next file transfer
            connectionContext.fileStarted = false;
            connectionContext.fileCompleted = true;
            connectionContext.fileName = null;
            connectionContext.fileLength = -1;

            // handle any remaining data in buffer
            if (buffer.remaining() > 0) {
                handleRead(key);
                return;
            }
        }

        buffer.compact();
    }

    private void saveFile(String filename, byte[] fileContent) throws IOException {
        File file = new File("files\\" + filename);

        System.out.println("Saving file " + filename);

        try (FileOutputStream outputStream = new FileOutputStream(file, true)) {
            int offset = 0;
            while (offset < fileContent.length) {
                int bytesToWrite = Math.min(BUFFER_SIZE, fileContent.length - offset);
                outputStream.write(fileContent, offset, bytesToWrite);
                offset += bytesToWrite;
            }
            outputStream.flush();
        }
        System.out.println("File " + filename + " saved successfully");
    }


    private void sendAck(SocketChannel clientSocketChannel, String filename) throws IOException {
        String ackMessage = String.format(ACK_MESSAGE_PREFIX, filename);
        byte[] ackMessageBytes = ackMessage.getBytes();
        ByteBuffer buffer = ByteBuffer.allocate(ackMessageBytes.length + Integer.BYTES);
        buffer.putInt(ackMessageBytes.length);
        buffer.put(ackMessageBytes);
        buffer.flip();

        while (buffer.hasRemaining()) {
            clientSocketChannel.write(buffer);
        }

        System.out.println("Sent acknowledgement for " + filename);
        buffer.clear(); // Очищаем буфер перед чтением новых данных
    }
}