我正在编写服务器以在客户端之间交换消息。尚待解决的一个问题是,当客户端恰好关闭时如何释放频道。我要做的是启动一个监视所有Client映射的监视线程,如果尝试对它进行write()时检测到异常,则我尝试尝试remove()一个通道。但是,关闭客户端后,监视线程中的write()方法不会引发异常,因此永远不会释放无用的通道。有人知道为什么吗?

public class ServerMonitor extends Thread{
private Map<String, SocketChannel> allClients;
private Set set;
private Iterator it;
private Entry entry;
private SocketChannel channel;
private ByteBuffer buf;

public ServerMonitor(Map<String, SocketChannel> allClients) {
    this.allClients = allClients;
    buf = ByteBuffer.allocateDirect(10);
    byte b = 0;
    buf.put(b);
    buf.flip();
}

public void run(){
    while(true) {
        if(!allClients.isEmpty()) {
            set = allClients.entrySet();
            it = set.iterator();
            while(it.hasNext()) {
                entry = (Entry) it.next();
                channel = (SocketChannel) entry.getValue();
                try{
                    channel.write(buf);
                } catch(Exception e) {
                    allClients.remove(entry.getKey());
                    //set.remove(entry);
                }
            }
        }
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


}

最佳答案

写入TCP套接字在本地进行缓冲,然后异步进行。因此,您不能依靠对等方关闭后的第一个写入失败。您可以依靠随后的写入失败,但是要到达此位置可能要花费大量写入。

关于java - SocketChannel的write()方法在应执行的操作时不会引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17235940/

10-10 18:26
查看更多