【发布时间】:2014-06-06 20:03:45
【问题描述】:
我正在编写一个服务器程序,它可以接受来自多个(但固定)数量的客户端的通信。我想让程序保持单线程。为此,我使用非阻塞套接字来迭代每个客户端,但每个客户端的通道都使用阻塞模式。这是我的服务器代码:
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(服务器的行为方式相同)。
【问题讨论】:
-
在服务器端,您永远不会关闭您的
ObjectOutputStream。您要么需要阅读直到获得EOF,要么在获得对象后关闭它并继续循环。 -
@Baldy 你是说 ObjectInputStream 吗?在服务器端,没有输出流,只有输入流。
-
是的,
ObjectInputStream。请参阅下面的答案。 -
@Baldy 请检查更新。在这种情况下它没有帮助。感谢您的调查。