Java nio Only Reading 8192/433000 байт - PullRequest
       23

Java nio Only Reading 8192/433000 байт

0 голосов
/ 11 декабря 2019

У меня есть проект, над которым я работаю, чтобы лучше понять 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 () вне цикла, даже после этого проблема сохраняется.

...