| 优缺点很明显。这里主要说下缺点:主要瓶颈在线程上。每个连接都会建立一个线程。虽然线程消耗比进程小,但是一台机器实际上能建立的有效线程有限,以Java来说,1.5以后,一个线程大致消耗1M内存!且随着线程数量的增加,CPU切换线程上下文的消耗也随之增加,在高过某个阀值后,继续增加线程,性能不增反降!而同样因为一个连接就新建一个线程,所以编码模型很简单! 就性能瓶颈这一点,就确定了BIO并不适合进行高性能服务器的开发!像Tomcat这样的Web服务器,从7开始就从BIO改成了NIO,来提高服务器性能! NIO //获取socket通道 SocketChannel channel = SocketChannel.open();         channel.configureBlocking(false); //获得通道管理器 selector=Selector.open();         channel.connect(new InetSocketAddress(serverIp, port)); //为该通道注册SelectionKey.OP_CONNECT事件 channel.register(selector, SelectionKey.OP_CONNECT); 
 while(true){     //选择注册过的io操作的事件(第一次为SelectionKey.OP_CONNECT)    selector.select();    while(SelectionKey key : selector.selectedKeys()){        if(key.isConnectable()){            SocketChannel channel=(SocketChannel)key.channel();            if(channel.isConnectionPending()){                channel.finishConnect();//如果正在连接,则完成连接            }            channel.register(selector, SelectionKey.OP_READ);        }else if(key.isReadable()){ //有可读数据事件。            SocketChannel channel = (SocketChannel)key.channel();            ByteBuffer buffer = ByteBuffer.allocate(10);            channel.read(buffer);            byte[] data = buffer.array();            String message = new String(data);            System.out.println("recevie message from server:, size:"                + buffer.position() + " msg: " + message);        }    } } 
 //获取一个ServerSocket通道 ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); serverChannel.socket().bind(new InetSocketAddress(port)); //获取通道管理器 selector = Selector.open(); //将通道管理器与通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件, serverChannel.register(selector, SelectionKey.OP_ACCEPT); 
 while(true){     //当有注册的事件到达时,方法返回,否则阻塞。    selector.select();    for(SelectionKey key : selector.selectedKeys()){        if(key.isAcceptable()){            ServerSocketChannel server =                 (ServerSocketChannel)key.channel();            SocketChannel channel = server.accept();            channel.write(ByteBuffer.wrap(             new String("send message to client").getBytes()));            //在与客户端连接成功后,为客户端通道注册SelectionKey.OP_READ事件。            channel.register(selector, SelectionKey.OP_READ);        }else if(key.isReadable()){//有可读数据事件            SocketChannel channel = (SocketChannel)key.channel();            ByteBuffer buffer = ByteBuffer.allocate(10);            int read = channel.read(buffer);            byte[] data = buffer.array();            String message = new String(data);            System.out.println("receive message from client, size:"                + buffer.position() + " msg: " + message);        }    } } 
 (编辑:南平站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |