最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文理清什么是BIO以及如何使用

 更新時間:2023年10月01日 11:29:13   作者:goyeer  
這篇文章主要介紹了什么是BIO以及如何使用,BIO英文全名是blockingIO,也叫做阻塞IO,是最容易理解、最容易實現(xiàn)的IO工作方式,本文就來通過一些簡單的示例為大家講講BIO吧,需要的朋友可以參考下

一、BIO概述

BIO(Blocking I/O)是傳統(tǒng)java io編程既同步阻塞IO,服務器實現(xiàn)模式為一個連接一個線程??蛻舳擞羞B接請求時服務器端就會新起一個線程進行處理。當線程空閑時為減少不必要的線程開銷,可以通過線程池機制改善。BIO方式適合用于連接數(shù)目比較小且固定的架構,這種方式對服務器資源要求比較高,并發(fā)局限應用中。

二、BIO工作機制

客戶端

  • 通過Socket對象請求與服務端建立連接。
  • 從Socket中得到字節(jié)輸入或者字節(jié)輸出流進行數(shù)據(jù)讀寫操作。

服務端

  • 通過ServerSocket注冊端口。
  • 服務端通過調用accept方法用于監(jiān)聽客戶端的Socket請求。
  • 從Socket中得到字節(jié)輸入或者字節(jié)輸出流進行數(shù)據(jù)讀寫操作。

三、同步阻塞步驟

  • 服務端啟動一個ServerSocket
  • 客戶端啟動Socket對服務器進行通信,默認情況下服務器端需要對每個客戶建立一個線程與之通訊。
  • 客戶端發(fā)出請求后,先咨詢服務器是否有線程響應,如果沒有則會等待,或者被拒絕。
  • 如果有響應,客戶端線程會等待請求結束后,在繼續(xù)執(zhí)行。

四、編碼實現(xiàn)傳統(tǒng)BIO

  • 傳統(tǒng)的同步阻塞模型開發(fā)中,服務端ServerSocket負責綁定IP地址,啟動監(jiān)聽端口;客戶端Socket負責 發(fā)起 連接操作。連接成功后,雙方通過輸入和輸出流進行同步阻塞式通信。
  • 基于BIO模式下的通信,客戶端-服務端是完全同步,完全藕合的。

服務端代碼

 public static void main(String[] args) {
        System.out.println("===服務端啟動===");
        ServerSocket serverSocket=null;
        try {
            serverSocket=new ServerSocket(5000);
            Socket socket=serverSocket.accept();
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String msg;
            if ((msg = br.readLine()) != null) {
                System.out.println("服務端接收客戶端信息為:" + msg);
            }
        }catch (Exception exception){
            System.out.println(exception.getMessage());
        }
  }

客戶端代碼

public static void main(String[] args) {
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1",5000);
            OutputStream os = socket.getOutputStream();
            PrintStream ps = new PrintStream(os);
            ps.println("Hi BIO! 與服務端通信成功");
            ps.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

總結

傳統(tǒng)BIO服務端會一直等待客戶端的消息,如果客戶端沒有進行消息的發(fā)送,服務端將一直進入阻塞狀態(tài),同時服務端是按照行獲取消息的,這意味著客戶端也必須按照行進行消息的發(fā)送,否則服務端將進 入等待消息的阻塞狀態(tài)。

五、BIO編程現(xiàn)實多發(fā)多收

BIO簡單方式是一個接收一個發(fā)送,如果實現(xiàn)多發(fā)多接收,下面將驗證多發(fā)多收的代碼

服務端代碼

public static void main(String[] args) {
    System.out.println("===服務端啟動===");
    try {
         ServerSocket ss = new ServerSocket(9988);
         Socket socket = ss.accept();
         InputStream is = socket.getInputStream();
         BufferedReader br = new BufferedReader(new InputStreamReader(is));
         String message;
         while ((message = br.readLine()) != null){
             System.out.println("服務端接收客戶端信息為:" + message);
         }
     } catch (IOException e) {
            e.printStackTrace();
     }
}

客戶端代碼

public static void main(String[] args) {
    try {
        Socket socket = new Socket("localhost",9988);
        OutputStream os = socket.getOutputStream();
        PrintStream ps = new PrintStream(os);
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("請輸入:");
            String input = scanner.nextLine();
            ps.println(input);
            ps.flush();
        }
     } catch (IOException e) {
            e.printStackTrace();
     }
}

六、BIO模擬客戶端服務端多對一

前面無論是一收一發(fā),還是多發(fā)多收都僅限一個客戶端,如何實現(xiàn)一個服務端對應多個客戶端哪,這個主要是更改服務端代碼

實現(xiàn)步驟

  • 監(jiān)聽tcp端口
  • while循環(huán)接收連接
  • 對接收到的連接進行InputStream/OutputStream操作

服務端實現(xiàn)

  public void listen() throws IOException {
        ServerSocket serverSocket = null;
        try {
            log.info("服務啟動監(jiān)聽");
            serverSocket = new ServerSocket(9988);
            //循環(huán)接收到客戶端的連接
            while (true) {
                Socket socket = serverSocket.accept();
                //得到連接后,開啟一個線程處理連接
                handleSocket(socket);
            }
        }finally {
            if(serverSocket != null){
                serverSocket.close();
            }
        }
 }
private void handleSocket(Socket socket) {
        HandleSocket socketHandle = new HandleSocket(socket);
        new Thread(socketHandle).start();
}
 public void run() {
        BufferedInputStream bufferedInputStream = null;
        BufferedOutputStream bufferedOutputStream  = null;
        try {
            bufferedInputStream = new BufferedInputStream(socket.getInputStream());
            byte[] bytes = new byte[1024];
            int len ;
            if ((len = bufferedInputStream.read(bytes)) > -1) {
                String result = new String(bytes,0,len);
                System.out.println("本次接收到的結果:"+result);
            }
            System.out.println("回復信息給客戶端:");
            bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
            String outString = Thread.currentThread().getName()+"接收到了";
            bufferedOutputStream.write(outString.getBytes());
            bufferedOutputStream.flush();
            System.out.println("回復完成:");
        } catch (IOException e) {
            System.out.println("異常:"e.getLocalizedMessage());
        } finally {
            System.out.println("關閉數(shù)據(jù)流:");
            try {
                if (bufferedInputStream != null) {
                    bufferedInputStream.close();
                }
                if (bufferedOutputStream != null) {
                    bufferedOutputStream.close();
                }
            }catch (IOException e){
                System.out.println("請輸入:"e.getLocalizedMessage());
            }
        }
    }

客戶端實現(xiàn)

1.與服務端建立連接

2.發(fā)送消息給服務端

3.接收服務端返回的消息

  public void start() throws IOException {
        Socket socket = new Socket("127.0.0.1", 8081);
        String msg = "Hi,This is the BioClient";
        //1.拿到輸出流
        //2.對輸出流進行處理
       System.out.println("請輸入:"+msg);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
        byte[] bytes = msg.getBytes();
        //3.輸出msg
        bufferedOutputStream.write(bytes);
        bufferedOutputStream.flush();
        System.out.println("發(fā)送完畢.");
        System.out.println("開始接收到消息.");
        //4.對輸入流進行處理
        BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
        byte[] inBytes = new byte[1024];
        int len;
        //5.讀取輸入流
        if ((len = bufferedInputStream.read(inBytes)) != -1) {
            String result = new String(inBytes, 0, len);
            System.out.println("接收到的消息="+result);
        }
        //6.關閉輸入輸出流
        bufferedOutputStream.close();
        bufferedInputStream.close();
        socket.close();
    }

七、總結

  • 每個Socket接收到,都會創(chuàng)建一個線程,線程的競爭、切換上下文影響性能;
  • 每個線程都會占用??臻g和CPU資源;
  • 并不是每個socket都進行l(wèi)O操作,無意義的線程處理;
  • 客戶端的并發(fā)訪問增加時。服務端將呈現(xiàn)1:1的線程開銷,訪問量越大,系統(tǒng)將發(fā)生線程棧溢出, 線程創(chuàng)建失敗,最終導致進程宕機或者僵死,從而不能對外提供服務;

以上就是一文理清什么是BIO以及如何使用的詳細內容,更多關于Java BIO的資料請關注腳本之家其它相關文章!

相關文章

  • Spring?Boot?+?Spring?Batch?實現(xiàn)批處理任務的詳細教程

    Spring?Boot?+?Spring?Batch?實現(xiàn)批處理任務的詳細教程

    這篇文章主要介紹了Spring?Boot+Spring?Batch實現(xiàn)批處理任務,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java中FilterInputStream和FilterOutputStream的用法詳解

    Java中FilterInputStream和FilterOutputStream的用法詳解

    這篇文章主要介紹了Java中FilterInputStream和FilterOutputStream的用法詳解,這兩個類分別用于封裝輸入和輸出流,需要的朋友可以參考下
    2016-06-06
  • Spring入門到精通之Bean標簽詳解

    Spring入門到精通之Bean標簽詳解

    這篇文章主要為大家詳細介紹了Spring中Bean的標簽,文中的示例代碼講解詳細,對我們學習Spring有一定的幫助,快跟隨小編一起學習學習吧
    2022-07-07
  • Java19新特性中結構化并發(fā)的使用

    Java19新特性中結構化并發(fā)的使用

    Java19在并發(fā)編程領域引入了一個全新的概念:結構化并發(fā),這一特性旨在簡化并發(fā)任務的管理,提升多線程程序的可維護性和安全性,使其生命周期和控制流更加有序和明確,感興趣的可以了解一下
    2024-09-09
  • SpringCloud使用feign調用錯誤的問題

    SpringCloud使用feign調用錯誤的問題

    這篇文章主要介紹了SpringCloud使用feign調用錯誤的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java發(fā)送帶html標簽內容的郵件實例代碼

    Java發(fā)送帶html標簽內容的郵件實例代碼

    下面小編就為大家?guī)硪黄狫ava發(fā)送帶html標簽內容的郵件實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-11-11
  • java?String拼接json的方式實現(xiàn)

    java?String拼接json的方式實現(xiàn)

    本文主要介紹了java?String拼接json的方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • Java基于直方圖應用的相似圖片識別實例

    Java基于直方圖應用的相似圖片識別實例

    這篇文章主要介紹了Java基于直方圖應用的相似圖片識別實例,是非常實用的技巧,多見于圖形里游戲中,需要的朋友可以參考下
    2014-09-09
  • MybatisPlus操作符和運算值詳解

    MybatisPlus操作符和運算值詳解

    在前端到后端的數(shù)據(jù)傳遞中,處理動態(tài)運算條件是一個常見的需求,本文介紹了如何在MybatisPlus中處理運算符和運算值的動態(tài)拼接問題,感興趣的朋友一起看看吧
    2024-10-10
  • Springboot如何使用Map將錯誤提示輸出到頁面

    Springboot如何使用Map將錯誤提示輸出到頁面

    這篇文章主要介紹了Springboot如何使用Map將錯誤提示輸出到頁面,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08

最新評論

井研县| 怀宁县| 开平市| 桐城市| 潮州市| 镇安县| 拉萨市| 黎城县| 吴桥县| 星座| 客服| 泽州县| 吉木乃县| 洪泽县| 翁牛特旗| 馆陶县| 遵义县| 孝感市| 苏尼特左旗| 雷波县| 上犹县| 基隆市| 黑水县| 双辽市| 敦煌市| 绥江县| 通化县| 巫山县| 隆尧县| 南召县| 台东市| 三亚市| 海兴县| 平远县| 昔阳县| 宜州市| 呼图壁县| 宁海县| 普宁市| 西吉县| 五大连池市|