有没有办法在没有多线程的情况下使用Java中的套接字编写多客户端程序?
我听说套接字映射但它是如何工作的?
我知道多线程,但是现在我不应该使用它。
答案 0 :(得分:2)
嗯,我把它扔在了一起。这只是用 java.nio 编程的一个例子。我认为这段代码非常简单。它将ServerSocket绑定到端口3000-3009。每当客户端发送数据时,它都会将其回送给它们。它可以处理尽可能多的连接。您当然应该实现更多的错误处理,但是更难以阅读以供参考。以这种方式处理数据比使用每个客户端线程方法要困难一些,如果您希望它可以使用混合类型服务器,其中非活动连接进入非阻塞模式,并且当您开始接收数据时,您可以跳回来使用缓存的线程池进入阻塞模式。
要测试它,只需打开一个shell并使用 telnet localhost 3000
Selector selector = Selector.open();
for(int port=3000;port<3010;port++){
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(port));
server.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Bound to " + server);
}
ByteBuffer buffer = ByteBuffer.allocate(0x4000);
while(selector.isOpen()){
selector.select();
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while(keys.hasNext()){
SelectionKey key = keys.next();
if(!key.isValid()) continue;
if(key.isReadable()){
buffer.clear();
SocketChannel socket = (SocketChannel)key.channel();
if(socket.read(buffer) == -1){ //-1 is end of stream
System.out.println("Client Disconnected " + socket);
socket.close();
continue;
}else{
buffer.flip();
socket.write(buffer); //echo data back to client
}
}else if(key.isAcceptable()){
ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
SocketChannel socket = serverChannel.accept();
socket.configureBlocking(false);
socket.register(selector, SelectionKey.OP_READ);
System.out.println("Client Connected " + socket);
}
}
selector.selectedKeys().clear();
}