当前位置: 代码迷 >> J2SE >> Java NIO 一直接收OP_ACCEPT的有关问题
  详细解决方案

Java NIO 一直接收OP_ACCEPT的有关问题

热度:72   发布时间:2016-04-24 01:29:08.0
Java NIO 一直接收OP_ACCEPT的问题
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
  相关解决方案