Java通信のIO進化(一)-BIO

3354 ワード

一、基本概念
BIOを共有する前に,ブロック/非ブロックとは何か,同期/非同期とは何かの概念を明らかにした.
1.ブロック/非ブロック:カーネル(メモリ)とスレッド(JVMのアプリケーション)の間のIO読み取りブロック.
2.同期/非同期:スレッドはカーネルデータを要求する時(ここではIOを指す)、待つ必要があるか(カーネルデータが準備される前に)、待つ場合は同期であり、待つ必要はない.
二、同期ブロック-BIO
ケース:サービス・リスニング・エンドを作成し、サーブレットの要求をリスニングし、戻りたいデータを返します.
手順:init()->start()->process
ServerSocketリスナーの作成、ポート8080の構成
private int port = 8080;

private ServerSocket serverSocket;

private Map servletMapping = new HashMap();

private Properties properties = new Properties();

 
//1、       ,  8080  ServerSocket  IP:localhost
//2、  web.xml     Servlet  HttpServlet
//   servlet-name
//   servlet-class
//   url-pattern
//3、    ,url-pattern    Servlet        
//   Map servletMapping

private void init(){
    //  web.xml  ,      ServletMapping  
    try {
        String WEB_INF = this.getClass().getResource("/").getPath();
        System.out.println(WEB_INF);
        FileInputStream io= new FileInputStream(WEB_INF + "web.properties");
        properties.load(io);
        for(Object object: properties.keySet()){
            String key = object.toString();
            if(key.endsWith(".url")){
                String servletName = key.replaceAll("\\.url$", "");
                String url = properties.getProperty(key);
                String className = properties.getProperty(servletName + ".className");
                //   ,   
                GServlet obj = (GServlet)Class.forName(className).newInstance();
                servletMapping.put(url, obj);
            }
        }
        io.close();
    }catch (Exception e){
        e.printStackTrace();
    }

}
private void start(){
    //   ,  web.properties
    init();
    try{
        serverSocket = new ServerSocket(this.port);
        System.out.println("GP Tomcat    ,      " + this.port);
        //2、      ,             
        while (true){
            Socket socket = serverSocket.accept();
            //4、HTTP  ,          ,       (HTTP  )
            process(socket);
        }
    }catch (Exception e){
        e.printStackTrace();
    }
}
private void process(Socket client) throws Exception{
    InputStream io = client.getInputStream();
    OutputStream os = client.getOutputStream();

    GRequest gRequest = new GRequest(io);
    GRespones gRespones = new GRespones(os);

    //5、        URL,    Servlet        
    String url = gRequest.getUrl();

    if(servletMapping.containsKey(url)){
        //6、        service()  ,       doGet/doPost  
        servletMapping.get(url).service(gRequest,gRespones);
    }else{
        gRespones.write("404 - Not Found");
    }

    os.flush();
    os.close();

    os.close();
    client.close();

}
public static void main(String[] args) {
    new GTomact().start();
}

三、閉塞原理
BIOは主にストリーム、InputStream、OutputStream、read、write向けの方法であり、様々なストリームがブロックされている.これは、1つのスレッドがread()またはwrite()を呼び出すと、一部のデータが読み出されるか、データが完全に書き込まれるまでスレッドがブロックされることを意味する.このスレッドはその間に何もできません.
Java BIOがストリームに面していることは、ストリームから1つ以上のバイトを読み出すたびに、すべてのバイトが読み込まれるまで、どこにもキャッシュされていないことを意味します.また、ストリーム内のデータを前後に移動することはできません.ストリームから読み込まれたデータを前後に移動する必要がある場合は、まずバッファにキャッシュする必要があります.