У меня есть проект, над которым я работаю, чтобы лучше понять Java NIO и сетевое программирование. Я пытаюсь отправить файл размером 400 000 байт через netcat на мой сервер, где он будет найден и записан в файл.
Проблема: Программа отлично работает, когда файлменьше 10 000 байт или когда я помещаю Thread.sleep (тайм-аут) перед Select (). Файл пересылается, но читает только 8192 байта, а затем отменяется из цикла и возвращается к select () для захвата остальных данных. Однако файл фиксирует, что происходит после. Мне нужны полные данные для дальнейшего расширения в проект.
Вещи, которые я пробовал: Я пытался загрузить данные в другой байтовый массив, который, очевидно, работает, но пропускает8192 байта (поскольку вызов select () был вызван снова). Читает остальную часть 391000 байтов. При сравнении файлов первые 8192 байта отсутствуют. Я пробовал разные вещи, но мне не хватает в NIO, чтобы понять, о чем я пишу.
Мой код
Именно здесь я чувствую, что код не работает(после отладки)
private void startServer() {
File temp = new File("Filepath");
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(listenAddress);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
log.info("Server Socket Channel Started");
while(!stopRequested){
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for(SelectionKey key : keys){
if(key.isAcceptable()){
try {
serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel socket = serverSocketChannel.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ);
}catch (IOException e) {
log.error("IOException caught: ", e);
}
}
if(key.isReadable(){ read(key); }
keys.remove(key);
}
}
} catch (IOException e) {
log.error("Error: ", e);
}
}
private void read(SelectionKey key) {
int count = 0;
File tmp = new File("Path");
try {
SocketChannel channel = (SocketChannel) key.channel();
byteBuffer.clear();
while((count = channel.read(byteBuffer)) > 0) {
byteBuffer.flip();
//in bytearrayoutputstream to append to data byte array
byteArrayOutputStream.write(byteBuffer.array(), byteBuffer.arrayOffset(), count);
byteBuffer.compact();
}
}
data = byteArrayOutputStream.toByteArray();
FileUtils.writeByteArrayToFile(tmp, data);
}
}
Приведенный выше код - это то, с чем я работаю. У меня есть больше вещей в этом классе, но я считаю, что две основные функции, имеющие проблему, это две. Я не слишком уверен, какие шаги я должен предпринять. Файл, который я должен протестировать, содержит много протоколов TCP около 400 000 байт. Select () собирает начальные 8192 байта, а затем запускает чтение (что не должно происходить до тех пор, пока не соберет все данные в потоке), возвращается и собирает остальное. Я выделил byteBuffer на 30720 байт.
Если не ясно, я могу опубликовать остальную часть кода, дайте мне знать, что вы предлагаете.
Вопрос
Почему этот код захватывает только 8192 байта, когда выделенное пространство составляет 30720? Почему он работает в режиме отладки или с Thread.sleep ()?
Предыдущий человек посоветовал мне поместить мой byteBuffer.clear () вне цикла, даже после этого проблема сохраняется.