使用套接字的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

有人知道如何解决吗?

安德烈·弗拉特利

好的,我设法将其投入使用。就是这样:

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

与其直接使用OutputStream,不如直接写入SocketChannel。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章