- Java code
import java.io.IOException;import java.net.InetAddress;import java.net.InetSocketAddress;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]; 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"; 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); //问题2:socketChannel 与 (SocketChannel)socketChannel.accept() 这两个channel什么区别 } else if(key.isAcceptable()){ //问题1:当一个客户端连接进来时,为什么这句话会一直重复地打印 System.out.println(key.hashCode()+" accepted"); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { TCP tcp = new TCP(); tcp.start(); }}
------解决方案--------------------
我晕。。。没仔细看你代码,你这代码整个逻辑都有问题
你在key.isAcceptable()里面没有做任何操作,实际上就是你根本就没有建立连接
该channel一直处于就绪状态,即使remove掉把selectedKey里面删除了,keys里面还是存在
下次select发现状态还是就绪就继续选择出来
你应该在key.isAcceptable()里面accept,然后将返回的socketChannel置为可读key