优缺点很明显。这里主要说下缺点:主要瓶颈在线程上。每个连接都会建立一个线程。虽然线程消耗比进程小,但是一台机器实际上能建立的有效线程有限,以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);
- }
- }
- }
(编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|