2015-05-24 3 views
0

Я пытаюсь перенаправить соединение на другой сервер с nio, Вот мой код, я думаю, что проблема заключается в ByteBuffer.rewind(), потому что этот код перенаправляет данные, но странным образом ,Java NIO Перенаправление связи

public static void main(String[] args) throws Exception { 

    ServerSocketChannel proxyServer = ServerSocketChannel.open(); 

    while (!Thread.interrupted()) { 

     SocketChannel clientChannel = proxyServer.accept(); 
     clientChannel.configureBlocking(false); 

     ByteBuffer uploadBuffer = ByteBuffer.allocate(1024 * 1024 * 5); 
     ByteBuffer downloadBuffer = ByteBuffer.allocate(1024 * 1024 * 5); 

     try { 
      SocketChannel serverChannel = SocketChannel.open(); 
      serverChannel.connect(
       new InetSocketAddress(
        "another server" 
        , 80 
       ) 
      ); 

      while (!Thread.interrupted()) { 

       // Client -> Server 
       if (clientChannel.read(uploadBuffer) < 0) { 
        throw new EOFException(); 
       } 

       uploadBuffer.rewind(); // <- maybe is this the error 
       while (uploadBuffer.hasRemaining()) { 
        serverChannel.write(uploadBuffer); 
       } 

       // Server -> Client 
       if (serverChannel.read(downloadBuffer) < 0) { 
        throw new EOFException(); 
       } 

       downloadBuffer.rewind(); // <- maybe is this? 
       while (downloadBuffer.hasRemaining()) { 
        clientChannel.write(downloadBuffer); 
       } 

       // Buffer reset 
       downloadBuffer.clear(); 
       uploadBuffer.clear(); 
      } 

     } catch (Exception exception) { 
      clientChannel.close(); 
     } 
    } 
    proxyServer.close(); 
} 

Возможно, мне нужно использовать флип?

+1

Что вы имеете в виду * этот код перенаправляет данные, но странным образом. *. Пожалуйста, будьте более конкретными! –

+0

@suman Я имею в виду, что загруженный/загруженный байт-буфер имеет некоторые проблемы, поскольку они не находятся в том же порядке, когда отправлены или возвращены – Emax

ответ

0

SocketChannel.read возвращает количество полученных байтов. Нет гарантии, что метод заполнил ByteBuffer.

Вы проверяете, является ли возвращенный счет отрицательным, но затем вы его отбрасываете. Что вам нужно сделать, так это обратить внимание на position ByteBuffer после каждого чтения. Как вы подозревали, метод flip() позаботится об этом. Типичное использование состоит в том, чтобы прочитать несколько байтов в ByteBuffer, а затем перевернуть этот буфер, чтобы он был готов к чтению другим кодом.

Итак, да, смена каждого из ваших rewind() звонков на flip() должна решить вашу проблему.