2014-09-05 1 views
0

Java nio를 사용하여 네트워킹을 할 때 문제가 있습니다.java nio가 쓰기 작업을 등록한 후에 읽을 수 없습니다.

스레드에서 서버를 시작하고 선택기에서 읽기 작업을 등록합니다. 다른 스레드가 서버에 연결됩니다.

  1. 클라이언트는
  2. 서버가
  3. 클라이언트가 응답을 다시 서버에 바이트 쓰기 클라이언트에 다시 datas와 바이트를 읽어 서버에 바이트를 씁니다.
  4. 서버 루프 2 단계

하지만 난 더 이상 선택에서 어떤 읽기 키를 얻을 수 없기 때문에 서버가 성공적으로 4 단계를 할 수 없습니다. 왜 ?? 전에 등록했는데 클라이언트가 데이터를 작성했습니다.

아래에있는 내 코드가있다 : 당신은 OP_WRITE의 채널을 다시 등록

package test; 

import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.nio.ByteBuffer; 
import java.nio.channels.SelectionKey; 
import java.nio.channels.Selector; 
import java.nio.channels.ServerSocketChannel; 
import java.nio.channels.SocketChannel; 
import java.util.Iterator; 


public class JavaNIO { 

    public static void main(String[] args) throws Exception { 
     final Selector selector = Selector.open(); 
     ServerSocketChannel serverChannel = ServerSocketChannel.open(); 
     serverChannel.configureBlocking(false); 
     serverChannel.socket().bind(new InetSocketAddress(5555)); 
     serverChannel.register(selector, SelectionKey.OP_ACCEPT); 
     new Thread() { 
      public void run() { 
       while(true) { 
        try { 
         long count = selector.select(); 
         if(count == 0) continue; 
         Iterator<SelectionKey> itKey = selector.selectedKeys().iterator(); 
         while(itKey.hasNext()) { 
          SelectionKey key = itKey.next(); 
          itKey.remove(); 
          if(key.isAcceptable()) { 
           ServerSocketChannel channel = (ServerSocketChannel)key.channel(); 
           SocketChannel socket = channel.accept(); 
           socket.configureBlocking(false); 
           socket.register(selector, SelectionKey.OP_READ); 

          } 
          if(key.isReadable()) { 
           ByteBuffer buffer= ByteBuffer.allocate(1); 
           SocketChannel channel = (SocketChannel)key.channel(); 
           while(true) { 
            buffer.flip(); 
            int len = channel.read(buffer); 
            if(len == 0) break; 
            buffer.clear(); 
           } 
           channel.read(buffer); 
           channel.register(selector, SelectionKey.OP_WRITE, null); 
          } 
          if(key.isWritable()) { 
           SocketChannel channel = (SocketChannel) key.channel(); 
           channel.write(ByteBuffer.wrap("ce".getBytes())); 
           key.cancel(); 
          } 
         } 
        } catch(Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     }.start(); 
     new Thread() { 
      public void run() { 
       try { 
        Socket socket = new Socket("localhost", 5555); 
        byte[] reads = new byte[1024]; 
        for(int i = 0; i < 1000; i++) { 
         socket.getOutputStream().write(new byte[]{1}); 
         socket.getInputStream().read(reads); 
         System.out.println(new String(reads)); 
        } 
       } catch (UnknownHostException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }.start(); 
    } 
} 

답변

1

, 그 interestOpsOP_READ을 포함하는 것을 정지 있도록이. 둘 다 원할 경우 그에 따라 변경하십시오. '또는'함께.

관련 문제