简体   繁体   English

Java中的多重套接字通信

[英]Muitiplexed socket communication in Java

I am writing a server program that can accept communication from multiple (but fixed) number of clients. 我正在编写一个服务器程序,该程序可以接受来自多个(但固定)数量的客户端的通信。 I want to keep the program single-threaded. 我想让程序保持单线程。 To do so, I am using non-blocking socket to iterate over each client, but each client's channel uses blocking mode. 为此,我使用非阻塞套接字在每个客户端上进行迭代,但是每个客户端的通道都使用阻塞模式。 Here's my server code: 这是我的服务器代码:

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);
            }
          }
        }
    }
}

The client uses simple blocking I/O, as shown here: 客户端使用简单的阻塞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);
         }
    }
}

The problem is that although the client wants to write 100 times, the server is reading the message just once. 问题是,尽管客户端要写100次,但服务器仅读取一次消息。 Neither the server nor the client is giving any exception, but I am only getting the output "Hello 0" from the server. 服务器和客户端均未给出任何异常,但是我仅从服务器获取输出“ Hello 0”。 Is there any problem in what I am doing here? 我在这里做什么有问题吗? If so, what alternatives do I have? 如果是这样,我有什么选择?

Thanks. 谢谢。

Update: Closing the ObjectInputStream within the server's loop gives a BrokenPipeException by the client (the server behaves in the same way). 更新:在服务器循环内关闭ObjectInputStream会导致客户端出现BrokenPipeException(服务器的行为方式相同)。

The issue is that you're just checking for new connections with key.isAcceptable() . 问题是您只是在使用key.isAcceptable()检查新连接。 You also need to check for reads with key.isReadble() . 您还需要使用key.isReadble()检查读取。 You should only be doing connection setup from key.isAcceptable() . 您应该只从key.isAcceptable()建立连接。

See Java ServerSocketChannel SocketChannel (Callback) 请参见Java ServerSocketChannel SocketChannel(回调)

The problem is that the server is not waiting for the client to send all it's data. 问题在于服务器不等待客户端发送所有数据。 In client server programs, what you need to do is to establish a clear protocol between both so that they are in sync when data is transmitted/received. 在客户端服务器程序中,您需要做的是在两者之间建立清晰的协议,以使它们在传输/接收数据时保持同步。 This is usually done by signaling an end of transmission by either side by sending a designated symbol or closing the connection when they are done 通常,这是通过发送指定符号或在连接完成后关闭连接来向任一方发送信号的传输结束信号来完成的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM