当我在学习NiO Java时出现了bug。当客户端断开连接时,服务器不会被阻塞.selector.select()总是返回1
答案 0 :(得分:0)
这是有道理的。套接字通道始终可读,read
始终返回EOF。
从频道中读取EOF后,您需要将其从选择器中删除。
答案 1 :(得分:0)
这是我的代码
package com.socket.Server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ImSocketServer {
private int port = 8888;
private Charset cs = Charset.forName("gbk");
private static ByteBuffer sBuffer = ByteBuffer.allocate(1024);
private static ByteBuffer rBuffer = ByteBuffer.allocate(1024);
private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();
private static Selector selector;
public ImSocketServer(int port){
this.port = port;
try {
init();
} catch (Exception e) {
e.printStackTrace();
}
}
private void init() throws IOException{
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
serverSocket.bind(new InetSocketAddress(port));
selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("server start on port:"+port);
}
private void listen(){
while (true) {
try {
System.out.println(selector.select());
Set<SelectionKey> selectionKeys = selector.selectedKeys();
for(SelectionKey key : selectionKeys){
try{
handle(key);
}
catch(Exception e){
System.out.println("挂了");
}
}
selectionKeys.clear();
selector.selectedKeys().clear();
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
private void handle(SelectionKey selectionKey) throws IOException {
ServerSocketChannel server = null;
SocketChannel client = null;
String receiveText=null;
int count=0;
if (selectionKey.isAcceptable()) {
server = (ServerSocketChannel) selectionKey.channel();
client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
client = (SocketChannel) selectionKey.channel();
rBuffer.clear();
count = client.read(rBuffer);
if (count > 0) {
rBuffer.flip();
receiveText = String.valueOf(cs.decode(rBuffer).array());
System.out.println(client.toString()+":"+receiveText);
dispatch(client, receiveText);
client = (SocketChannel) selectionKey.channel();
client.register(selector, SelectionKey.OP_READ);
}
}
}
private void dispatch(SocketChannel client,String info) throws IOException{
Socket s = client.socket();
String name = "["+s.getInetAddress().toString().substring(1)+":"+Integer.toHexString(client.hashCode())+"]";
if(!clientsMap.isEmpty()){
for(Map.Entry<String, SocketChannel> entry : clientsMap.entrySet()){
SocketChannel temp = entry.getValue();
if(!client.equals(temp)){
sBuffer.clear();
sBuffer.put((name+":"+info).getBytes());
sBuffer.flip();
temp.write(sBuffer);
}
}
}
clientsMap.put(name, client);
}
public static void main(String[] args) throws IOException {
ImSocketServer server = new ImSocketServer(7777);
server.listen();
}
}
&#13;