2012-06-21 3 views
1

채팅 응용 프로그램을 구축하는 것이 매우 익숙합니다. 모든 클라이언트에서 연결이 있지만 클라이언트의 콘텐츠를 읽는 동안 java.nio.channels.IllegalBlockingModeException이 있습니다. 여기서 예외가 발생하는 코드를 도와주세요.java.nio.channels.IllegalBlockingModeException 채널을 통해 클라이언트에서 콘텐츠를 읽는 중

public class Server 
{ 

    private Selector selector; 

private ServerSocketChannel channel; 

    public void listner() 
    { 

      try 
    { 
     this.selector = Selector.open(); 
     this.channel = ServerSocketChannel.open(); 
     this.channel.configureBlocking(false); 
     this.channel.socket().bind(new InetSocketAddress(8888)); 
     this.channel.register(this.selector, 16); 
    } 
    catch (IOException e) 
    { 
     throw new RuntimeException("Could not register listener", e); 
    }} 


    public void non_Socket()throws Exception 
    { 

     try 
     { 
      int i=0; 
      this.channel = ServerSocketChannel.open(); 
      this.channel.configureBlocking(false); 
      this.channel.socket().bind(new InetSocketAddress(80)); 

      while(true) 
      { 

       this.selector = Selector.open(); 
       this.channel.register(this.selector, 16); 

       Set<SelectionKey> keys = this.selector.selectedKeys(); 
       Iterator<SelectionKey> iterator = keys.iterator(); 
       int readyChannels = selector.select(); 
       if(readyChannels == 0) continue; 
       Set<SelectionKey> selectedKeys = selector.selectedKeys(); 
       Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); 
       while(keyIterator.hasNext()) 
       { 
        SelectionKey key = keyIterator.next(); 
        if(key.isAcceptable()) 
        { 
          // a connection was accepted by a ServerSocketChannel. 
          System.out.println("a connection was accepted by a ServerSocketChannel"); 
          SocketChannel sc = this.channel.accept(); 
          sc.configureBlocking(false); 
          System.out.println("Received an incoming connection from " + sc.socket().getRemoteSocketAddress()); 
          System.out.println("checking 0101"); 
          // new PrintRequest(sc,i).start(); 
          System.out.println("checking 0110"); 

          if(sc == null) 
          { 
           System.out.println("Please login"); 
           Thread.sleep(6000); 
          } 
          else 
          { 
           System.out.println("Last Login was successful"); 
           // new PrintRequest(sc,i).start(); 
           PrintRequest pr=new PrintRequest(sc,i); 
           new Thread(pr).start(); 

          } 


        } 
        else if (key.isConnectable()) 
        { 
          // a connection was established with a remote server. 
         System.out.println("a connection was established with a remote server"); 


        } 
        else if (key.isWritable()) 
        { 
         // a channel is ready for writing 
         System.out.println(" a channel is ready for writing"); 
        } 

        else if (key.isReadable()) 
        { 
         // a channel is ready for reading 
         System.out.println(" a channel is ready for Reading"); 
        } 
        System.out.println(" a channel is prepare for Reading"); 
        keyIterator.remove(); 
        Thread.sleep(5000); 
       } 

      } 
     } 

     catch(Exception E) 
     { 
      System.out.println(" Here : "+E); 
     } 
     finally 
       { 
        if (channel != null) 
        { 
        try 
        { 
          channel.close(); 
        } 
        catch (Exception e) 
        { 
          e.printStackTrace(); 
        } 
        } 
       } 
    } 


    public static void main(String [] abc) throws Exception 
    { 
     new Server().non_Socket(); 
    }} 

클라이언트 측 : PrintRequest class 예외의 while (rbc.read(b) != -1)에 도달하는

public class PrintRequest extends Thread 
{ 

    public PrintRequest(SocketChannel sc,int i)throws Exception 
    { 
     System.out.println("going to enter the try block of PrintRequest");   
     try 
     { 
       System.out.println("Am in the try block of PrintRequest");  

       ReadableByteChannel rbc = Channels.newChannel(sc.socket().getInputStream()); 
       System.out.println("checking in PrintRequest 0001"); 
       WritableByteChannel wbc = Channels.newChannel(System.out); 
       System.out.println("checking in PrintRequest 0010"); 
       ByteBuffer b = ByteBuffer.allocateDirect(1024); // read 1024 bytes 
       // int numBytesRead = sc.read(b); 
       System.out.println("checking in PrintRequest 0011"); 
       while (rbc.read(b) != -1) 
       { 
        System.out.println("Am in while loop of PrintRequest "); 
        b.flip(); 
        while (b.hasRemaining()) 
        { 
         wbc.write(b); 
         System.out.println(); 
        } 
        b.clear(); 
       } 

     } 
     catch(Exception E) 
     { 
      System.out.println("Exception in printlnRequest "+E); 
     }       
    } } 

내 서버 코드를 occures 동안

public class Client 
{ 

    public void non_Client_Socket() 
    { 
     SocketChannel sChannel=null; 
     try 
     { 
      sChannel = SocketChannel.open(); 
      sChannel.connect(new InetSocketAddress("localhost", 80)); 
      while (!sChannel.finishConnect()) 
      { 
       System.out.println("Channel is not connected yet"); 
       Thread.sleep(5000); 
      } 

      System.out.println("Channel is ready to use"); 

      /* ---------- going to send data to server ------------*/ 
      System.out.println("please enter the text"); 
      BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in)); 
      while(true) 
       { 
        System.out.println("Enter the text"); 
        String HELLO_REQUEST =stdin.readLine().toString(); 
        if(HELLO_REQUEST.equalsIgnoreCase("end")) 
        { 
         break; 
        } 

        System.out.println("Sending a request to HelloServer");  
        ByteBuffer buffer = ByteBuffer.wrap(HELLO_REQUEST.getBytes());  
        sChannel.write(buffer); 
       } 
     } 
     catch(Exception E) 
     { 

     } 

     finally 
     {  
      if (sChannel != null) 
      {    
       try 
       {    
        sChannel.close();    
       } 
       catch (Exception e) 
       {   
        e.printStackTrace();  
       }  
      } 

     } } 
     /* ---------- the data is written in sChannel server will read from this channel ------------ */ 




    public static void main(String [] args)throws Exception 
    { 
     new Client().non_Client_Socket(); 
    }} 
+0

계속 [서버가 nio에서 하나 이상의 클라이언트를 허용하지 않음] (http://stackoverflow.com/questions/11099927/server-not-accepting-morethan-one-client-in-io) – EJP

답변

4
ReadableByteChannel rbc = Channels.newChannel(sc.socket().getInputStream()); 

귀하의 문제는 여기에있다. 비 차단 모드 인 채널의 스트림은 사용할 수 없습니다. 어쨌든 sc은 이미 ReadableByteChannel이므로 코드는 무의미합니다. 이 행을 삭제하고 rbc 대신 sc으로 다음 I/O를 수행하십시오. 그러나 아래를보십시오.

아직 previous post에서 언급 한 문제가 해결되지 않았습니다. 연결 기술이 여전히 잘못되어 있으며 OP_READ에 대해 허용 된 채널을 등록하는 대신 비 차단 모드에서 읽기를 반복하는 PrintRequest()를 호출하고 있습니다. 코드는 계속해서 말이되지 않습니다.

+0

고맙습니다 ... ... 'OP_READ에 대해 허용 된 채널을 등록하는 대신 비 차단 모드에서 읽기를 반복하는 PrintRequest()를 호출하고 있습니다. 자세한 내용을 설명해주십시오. . . . – Amith

+0

@Amith 비 차단 모드에서 루프를 읽지 않아야합니다. 'OP_READ'가 실행될 때까지 기다려야합니다. 즉, isReadable() 블록을 입력하고 거기서 읽습니다. 'read()'반환 값이'0'이 될 때까지 반복 할 수 있습니다. select 루프로 되돌아 가야 할 때, 또는 채널을 닫아야 할 때'-1'을 반환해야합니다. – EJP

+0

대단히 고마워 ......... 나는 그것을 지금 시도 할 것이지만, isReadable 조건에 들어 가지 않을 것이다. – Amith

관련 문제