2013-12-23 25 views
0

我正在尝试编写使用套接字的聊天服务器和客户端。连接客户端正常工作,我从服务器获取输出正确的:使用套接字的IllegalBlockingModeException

Listening on port 8000 
Got connection from Socket[addr=/127.0.0.1,port=50628,localport=8000] 

但是,当我从客户端发送的东西,我得到IllegalBlockingModeException异常。下面是我有:

public void listen() 
    { 
     try { 
      // Open a non-blocking socket channel 
      ServerSocketChannel ssc = ServerSocketChannel.open(); 
      ssc.configureBlocking(false); 

      // Get the socket and bind it 
      ServerSocket ss = ssc.socket(); 
      InetSocketAddress isa = new InetSocketAddress(this.getServerName(), this.getServerPort()); 
      ss.bind(isa); 

      // Create the selector 
      Selector selector = Selector.open(); 
      ssc.register(selector, SelectionKey.OP_ACCEPT); 
      System.out.println("Listening on port " + this.getServerPort()); 

      while (true) 
      { 
       // Wait for at least one channel to be selected 
       if (selector.select() == 0) 
        continue; 

       // Iterate the key set and dispatch messages 
       Set keys = selector.selectedKeys(); 
       Iterator it = keys.iterator(); 

       while (it.hasNext()) 
       { 
        SelectionKey key = (SelectionKey)it.next(); 
        if (key.isAcceptable()) { 
         Socket s = ss.accept(); 
         System.out.println("Got connection from " + s); 
         SocketChannel sc = s.getChannel(); 
         sc.configureBlocking(false); 
         sc.register(selector, SelectionKey.OP_READ); 
        } 
        else if (key.isReadable()) { 
         SocketChannel sc = null; 
         try { 
          sc = (SocketChannel)key.channel(); 
          String message = processInput(sc); 

          if (message == null) { 
           key.cancel(); 
           Socket s = null; 
           try { 
            s = sc.socket(); 
            System.out.println("Closing connection to " +s); 
            s.close(); 
           } catch(IOException ie) { 
            System.err.println("Error closing socket " + s + ": " + ie); 
           } 
          } 
          else { 
           String response = getListener().process(sc, message); 
                    ObjectOutputStream oos = new ObjectOutputStream(Channels.newOutputStream(sc)); 
           //ObjectOutputStream oos = new ObjectOutputStream(sc.socket().getOutputStream()); 
           oos.writeObject(response + "\n"); 
           oos.close(); 
          } 
         } 
         catch(IOException ie) { 
          key.cancel(); 
          try { 
           sc.close(); 
          } catch(IOException ie2) { 
           System.out.println(ie2); 
          } 
          System.out.println("Closed " + sc); 
         } 
        } 
       } 
       keys.clear(); 
      } 
     } 

     catch (IOException ex) { 
      System.out.println(ex); 
      System.exit(1); 
     } 
    } 

    private String processInput(SocketChannel sc) throws IOException { 

     buffer.clear(); 
     sc.read(buffer); 
     buffer.flip(); 

     if (buffer.limit()==0) { 
      return null; 
     } 

     return decoder.decode(buffer).toString(); 
    } 

这里的堆栈跟踪:

java.nio.channels.SocketChannel[connected local=/127.0.0.1:8000 remote=/127.0.0.1:50656] 
Exception in thread "main" java.nio.channels.IllegalBlockingModeException 
    at java.nio.channels.Channels.writeFully(Channels.java:97) 
    at java.nio.channels.Channels.access$000(Channels.java:61) 
    at java.nio.channels.Channels$1.write(Channels.java:174) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1870) 
    at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1779) 
    at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:247) 
    at ChatServer$Server.listen(ChatServer.java:171) 
    at ChatServer.run(ChatServer.java:231) 
    at ChatServer.main(ChatServer.java:247) 
Java Result: 1 

有谁知道如何解决这个问题?

+0

Upvoted无意义无法解释的downvote。 – EJP

+0

谢谢=)我也不明白它.. –

回答

0

好吧,我设法使它工作。方法如下:

String response = getListener().process(sc, message) + "\n"; 
ByteBuffer bb = ByteBuffer.wrap(response.getBytes("utf-8")); 
sc.write(bb); 

而不是使用OutputStream,直接写入SocketChannel。

0

您无法在非阻塞模式下在通道上使用Channels.newXXXStream()。看到Javadoc。

+0

但如何呢? = \我设法创建与OutputStream os = Channels.newOutputStream(sc)的流,但现在它失败时,我试图写 –

+0

因为你不能这样做。您无法在非阻塞通道上使用阻塞I/O。 – EJP