服务端代码:import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class TCP { ServerSocketChannel socketChannel;
Selector selector;
int port = 8778;
String[] opsName=new String[17];
ByteBuffer buffer;
int count = 0;
public TCP(){
opsName[SelectionKey.OP_ACCEPT]="OP_ACCEPT";
opsName[SelectionKey.OP_CONNECT]="OP_CONNECT";
opsName[SelectionKey.OP_READ]="OP_READ";
opsName[SelectionKey.OP_WRITE]="OP_WRITE";
buffer =ByteBuffer.allocate(10);
try {
socketChannel=ServerSocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.socket().setReuseAddress(true);
socketChannel.socket().bind(new InetSocketAddress(port));
selector=Selector.open();
System.out.println(socketChannel.hashCode());

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void start(){
try {
socketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (ClosedChannelException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("server start port "+port);
while(true){

int n;
try {
System.out.print("wait...");
n = selector.select(60000);
System.out.println(n);
if(n<=0)continue;

Iterator<SelectionKey> it = selector.selectedKeys().iterator();
while(it.hasNext()){
SelectionKey key = it.next();
it.remove();
System.out.println("key:"+opsName[key.interestOps()]+","+key.channel().hashCode());
if(key.isReadable()){
System.out.println(key.hashCode()+" isReadable");
socketChannel.accept().register(selector, SelectionKey.OP_READ);

}

else if(key.isAcceptable()){

System.out.println(key.hashCode()+" accepted");
SocketChannel client =socketChannel.accept();
client.configureBlocking(false);
//client.register(selector, SelectionKey.OP_WRITE);
//SocketChannel client =(SocketChannel) key.channel();
buffer.clear();
buffer.putInt(count++);
buffer.flip();
client.write(buffer);
System.out.println(client.hashCode()+" write..");
}
else if(key.isWritable()){

}

}

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
} public static void main(String[] args) {
TCP tcp = new TCP();
tcp.start();
}
}
客户端连接进来后获取一个int就断开,在哪里可以捕获到断开事件?

解决方案 »

  1.   

    TCP 连接属于 全双工的。情况很多很复杂。如果  客户端断开连接,服务器端会读到 -1 你处理读入事件加入判断读入是否为 -1 , 就可以。如下面标准代码 private void read(SelectionKey key) throws IOException   {
     readBuffer.clear();
     SocketChannel socketChannel=(SocketChannel) key.channel();
     int num=0;
     try {
     
    num=socketChannel.read(readBuffer);

    } catch(IOException e) {
       key.cancel();
      socketChannel.close();
        return ;
    }
    if(num==-1){
                key.channel().close();
                key.cancel();
                           return;
    }
      workerPool.processData(this, socketChannel, readBuffer.array(),num );

    }