Java中的多路复用套接字通信

时间:2014-06-06 20:03:46

标签: java sockets socket.io

我正在编写一个服务器程序,可以接受来自多个(但固定)数量的客户端的通信。我想保持程序单线程。为此,我使用非阻塞套接字迭代每个客户端,但每个客户端的通道使用阻塞模式。这是我的服务器代码:

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

        ServerSocketChannel channel = ServerSocketChannel.open();
        channel.configureBlocking(false);
        channel.socket().bind(new java.net.InetSocketAddress("localhost", 8005));
        System.out.println("Server attivo porta 8005");
        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_ACCEPT);

        for(;;) {
          selector.select();
          Set keys = selector.selectedKeys();
          Iterator i = keys.iterator();

          while(i.hasNext()) {
            SelectionKey key = (SelectionKey) i.next();

            i.remove();

            if (key.isAcceptable()) {
              SocketChannel client = channel.accept();
              client.configureBlocking(true);

              ObjectInputStream ois = new ObjectInputStream(
                    client.socket().getInputStream());
              String s = (String)ois.readObject();
              System.out.println(s);
            }
          }
        }
    }
}

客户端使用简单的阻塞I / O,如下所示:

class client {
    public static void main(String args[]) throws Exception {
        SocketChannel channel = SocketChannel.open();

        channel.configureBlocking(true);

        channel.connect(new java.net.InetSocketAddress("localhost", 8005));

        ObjectOutputStream oos = new ObjectOutputStream
              (channel.socket().getOutputStream());

        for (int i = 0; i < 100; i++) {
             oos.writeObject(new String("Hello " + i));
             System.out.println(i);
         }
    }
}

问题是虽然客户端想要写100次,但服务器只读取一次消息。服务器和客户端都没有给出任何异常,但我只是从服务器获得输出“Hello 0”。我在这里做什么有什么问题吗?如果是这样,我有什么替代方案?

感谢。

更新:关闭服务器循环中的ObjectInputStream会导致客户端出现BrokenPipeException(服务器的行为方式相同)。

2 个答案:

答案 0 :(得分:1)

问题是您只是在检查key.isAcceptable()的新连接。您还需要使用key.isReadble()检查读取。您应该只从key.isAcceptable()进行连接设置。

请参阅Java ServerSocketChannel SocketChannel (Callback)

答案 1 :(得分:0)

问题是服务器没有等待客户端发送它的所有数据。在客户端服务器程序中,您需要做的是在两者之间建立清晰的协议,以便在发送/接收数据时它们保持同步。这通常是通过发送指定符号或在完成连接时关闭连接来发出传输结束的信号来完成