BIO、NIO区别总结

BIO、NIO区别总结

BIO方式是java1.4之前支持的传统socket编程方式,socket.accept()会阻塞。在任何时间点,只有一个客户端能占用数据通道。如客户端有数据延迟,通道出现阻塞。

NIO:监听注册事件,客户端连接转换为事件,供服务端处理。

 

对于如下情况,BIO、NIO表现。

 

等待数据时间

服务端处理数据时间

Request1

10s

1s

Request2

1s

2s

 

  1. 多线程处理请求

BIO等待时间=10+1+2=13s

NIO等待时间=1+2+7+1=11s

  1. 单线程处理请求

BIO等待时间=10+1+1+2=14s

NIO等待时间=1+2+7+1=11s

 

BIO、NIO模拟http

  1. BIOServer

package tomcat;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class BioTomcat {
   
public static void sendResponse(Socket socket) throws IOException {
       
OutputStream outputStream = socket.getOutputStream();
       
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outputStream));
       
String show = "

BIOServer!!!" + new Date().getSeconds() + "

" +
               
"今天是20181213日 星期四" +
               
"" ;
       
out.write("HTTP/1.0 200 OK");
       
out.newLine();
       
//返回一个首部
       
out.write("Content-Type:text/html");
       
out.newLine();
        
out.write("Content-Length: " + show.length() );
       
out.newLine();
       
out.write("charset=gbk");
       
out.newLine();
       
// 根据 HTTP 协议, 空行将结束头信息
       
out.newLine();
       
// 输出请求资源
       
out.write(show);
       
out.newLine();
        
out.flush();
       
out.close();

    }

   
public static void main(String[] args) throws IOException {
       
ServerSocket server = new ServerSocket(8088);
       
System.out.println("服务器启动:8088");
       
while (true){
           
Socket socket = server.accept();
           
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
           
String line = null;
           
while ((line = reader.readLine()) != null && !line.isEmpty()){
               
System.out.println(line);
            }
           
sendResponse(socket);
           
socket.close();
        }
    }
}

BIO、NIO区别总结_第1张图片

  1. NIOServer
package tomcat;

import java.io.*;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.CharBuffer;

import java.nio.channels.SelectionKey;

import java.nio.channels.Selector;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.charset.Charset;

import java.nio.charset.CharsetDecoder;

import java.util.Date;

import java.util.Iterator;

import java.util.Set;

public class NioTomcat {

    public static String getString(ByteBuffer buffer) {

        Charset charset = null;

        CharsetDecoder decoder = null;

        CharBuffer charBuffer = null;

        try

        {

            charset = Charset.forName("UTF-8");

            decoder = charset.newDecoder();

            charBuffer = decoder.decode(buffer.asReadOnlyBuffer());

            return charBuffer.toString();

        }

        catch (Exception ex)

        {

            ex.printStackTrace();

            return "";

        }

    }

    private static void listen(Selector selector) throws IOException {

        while (true){

            int wait = selector.select(1000);

            if (wait == 0){

                continue;

            }

            Set<SelectionKey> keys = selector.selectedKeys();

            Iterator<SelectionKey> iterator = keys.iterator();

            while (iterator.hasNext()){

                SelectionKey key = iterator.next();

                handle(key, selector);

                iterator.remove();

            }

        }

    }

    public static void handle(SelectionKey key, Selector selector) throws IOException {

        if (key.isAcceptable()){

            ServerSocketChannel server = (ServerSocketChannel)key.channel();

            server.accept().configureBlocking(false).register(selector, SelectionKey.OP_READ);

        } else if (key.isReadable()){

            SocketChannel socketChannel = (SocketChannel) key.channel();

            ByteBuffer buffer = ByteBuffer.allocate(1024);

            socketChannel.read(buffer);

            buffer.flip();

            System.out.println(getString(buffer));

            socketChannel.register(selector, SelectionKey.OP_WRITE);

        } else if (key.isWritable()){

            SocketChannel socketChannel = (SocketChannel) key.channel();

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);

            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(byteArrayOutputStream));

            String show = "

NIOServer!!!" + new Date().getSeconds() + "

" +                     "今天是20181213日 星期四" +                     "" ;             writer.write("HTTP/1.0 200 OK");             writer.newLine();             writer.write("Content-Type:text/html");             writer.newLine();             writer.write("Content-Length: " + show.length() );             writer.newLine();             writer.newLine();             writer.write(show);             writer.flush();             writer.close();             socketChannel.write(ByteBuffer.wrap(byteArrayOutputStream.toByteArray()));             socketChannel.close();         }     }     public static void main(String[] args) throws IOException {         ServerSocketChannel server = ServerSocketChannel.open();         server.bind(new InetSocketAddress(8000));         server.configureBlocking(false);         Selector selector = Selector.open();         server.register(selector, SelectionKey.OP_ACCEPT);         System.out.println("服务器启动8000");         listen(selector);     } }

BIO、NIO区别总结_第2张图片

你可能感兴趣的:(服务器)