• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • JAVA網絡編程:BIO

    標簽: JAVA

    首先安裝netcat(window安裝教程)來模擬客戶端

    BIO(Blocking IO)顧名思義阻塞式IO

    在服務端的主要實現代碼是

    ServerSocket.accept();
    InputStream.read(), OutputStream.write()
    

    這些方法都是阻塞的方法,沒有請求就會一直阻塞直到有新連接進來,或數據輸入輸出

    單線程BIO
    public class ServerBio {
        public static void main(String[] args) throws IOException {
        	//監聽9000端口
            ServerSocket serverSocket = new ServerSocket(9000);
            while (true) {
                //未有連接,阻塞
                Socket socket = serverSocket.accept();
                System.out.println("一個新的連接進來");
    
                handler(socket);
                socket.close();
            }
        }
    
        private static void handler(Socket socket) throws IOException {
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            //循環讀出一次傳過來的所有字節
            while (true) {
                int read = inputStream.read(bytes);
                if (read != -1) {
                    System.out.println(new String(bytes, 0, read));
                } else {
                    break;
                }
    
            }
        }
    }
    

    打上斷點,調試運行程序
    在這里插入圖片描述
    下一步,可以看到程序阻塞在socket的accept方法,等待連接進來
    在這里插入圖片描述
    accept方法也詳細說明了阻塞知道一個連接建立
    在這里插入圖片描述
    用先前安裝好的netcat作為客戶端發起連接,可以看到程序取消阻塞,執行下一步
    在這里插入圖片描述
    一直點擊下一步,來到下圖,因為客戶端沒有發數據過來,所以read方法又阻塞
    在這里插入圖片描述
    InputStream的read方法注釋
    在這里插入圖片描述
    在nc命令端輸入數據,就會傳送到服務端
    在這里插入圖片描述
    當服務器接收完數據之后,只要客戶端還保持連接,read就不會等于-1,又阻塞在read方法等待客戶端的數據
    在這里插入圖片描述
    還是read注釋:如果socket流關閉了read方法就會返回-1
    在這里插入圖片描述
    現在我們來新開一個客戶端連接同樣的端口,可以發現由于程序阻塞在read方法,并沒有接收到新客戶端的連接
    在這里插入圖片描述
    在新客戶端發的消息服務器理所當然也沒有接收,因為服務器當是單線程的,正在阻塞等待舊客戶端的數據過來
    在這里插入圖片描述
    那為什么第二個連接還在等待連接呢,現在關閉第一個客戶端連接,發現服務器出錯了,原因是客戶端連接斷開->stream退出,服務器的socket并沒有拿到輸入流,所以拋出異常
    在這里插入圖片描述
    下面將代碼完善一下,在客戶端輸入結束字符讓服務器結束本次socket的連接,這樣就不會拋出異常了

        private static void handler(Socket socket) throws IOException {
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket.getInputStream();
            while (true) {
                int read = inputStream.read(bytes);
                String msg = new String(bytes, 0, read);
                if("end\n".equals(msg)) break;
                if (read != -1) {
                    System.out.println(new String(bytes, 0, read));
                } else {
                    break;
                }
    
            }
        }
    

    可以看到客戶端自己結束后,剛阻塞的新連接也連接成功了
    在這里插入圖片描述 在這里插入圖片描述

    線程池實現的BIO

    每有一次客戶端的連接進來,就會在\color{red}{線程池}分配一個線程來執行這個連接,從下圖可以看到紅色的虛線是請求服務器并且分配線程,建立連接后雙方就可以互相通信(黑色實線)
    在這里插入圖片描述

    代碼實現
    public class ServerThreadBio {
        public static void main(String[] args) throws IOException {
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            //監聽9000端口
            ServerSocket serverSocket = new ServerSocket(8000);
            while (true) {
                //未有連接,阻塞
                final Socket socket = serverSocket.accept();
                System.out.println("一個新的連接進來");
    
                newCachedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            handler(socket);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
    
    
            }
        }
    
        private static void handler(Socket socket) throws IOException {
            try{
                byte[] bytes = new byte[1024];
                InputStream inputStream = socket.getInputStream();
                while (true) {
                    int read = inputStream.read(bytes);
                    if (read != -1) {
                        System.out.println(new String(bytes, 0, read));
                    } else {
                        break;
                    }
    
                }
    
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                socket.close();
            }
    
        }
    }
    

    可以看到服務器能同時處理兩個客戶端的連接請求的數據了
    在這里插入圖片描述
    可以看到線程池有兩個線程 Running
    在這里插入圖片描述

    版權聲明:本文為weixin_40633275原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_40633275/article/details/106594447

    智能推薦

    BIO網絡編程

    BIO網絡編程 服務端 客戶端 處理多連接 HTTP協議 請求數據包解析 響應數據包解析 響應狀態碼 協議開發---http協議 阻塞IO的含義 服務端 客戶端 處理多連接 使用線程池,多線程技術 HTTP協議 瀏覽器和服務端交互的時候,使用的http協議。 請求數據包解析 響應數據包解析 響應狀態碼 協議開發—http協議 添加以下代碼,可以與瀏覽器進行交互。 想在Socket之上,...

    BIO網絡編程

    前言 之前我們已經了解了網絡編程它是有操作系統統一的API的,每種語言又有不同的實現,所以本文主要講述java最開始的一個Socket版本,使用java怎么去做一個BIO的網絡編程,一步步開發根據現有問題升級改造,直到服務端能處理多個請求且能夠支持HTTP網絡協議 服務端-單線程處理 服務端代碼 客戶端代碼 執行步驟和運行結果 1.先執行服務端成功后再執行客戶端 2.服務端打印收到客戶端的連接 3...

    Java網絡編程之Tcp通信 (BIO) - 簡單通信

    1. 你需要了解以下知識: Tcp協議的原理。 Java Socket是什么。 Tcp協議原理: TCP(Transmission Control Protocol 傳輸控制協議)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,由IETF的RFC793定義。在簡化的計算機網絡OSI模型中,它完成第四層傳輸層所指定的功能,用戶數據報協議(UDP)是同一層內  另一個重要的傳輸協議。在...

    Java 網絡編程實戰筆記:BIO、NIO、AIO

    Java 網絡編程學習筆記 前置概念 Java IO 模型 IO 模型 對應的 Java 版本 BIO(同步阻塞 IO) 1.4 之前 NIO(同步非阻塞 IO) 1.4 AIO(異步非阻塞 IO) 1.7 Linux 內核 IO 模型 阻塞 IO 最傳統的一種 IO 模型,在讀寫數據過程中會發生阻塞。 當用戶線程發出 IO 請求后,內核會去查看數據是否就緒,如果沒有就緒就會等待數據就緒,而用戶線...

    網絡編程之Java BIO 概念及代碼使用demo

    JAVA BIO Socket 服務端代碼demo 代碼只有Server端測試用的 telnet工具,代碼后邊有測試過程。 使用測試: 啟動服務器端 使用telnet 客戶端連接并發送數據 服務器端收到消息并打印結果:...

    猜你喜歡

    Java網絡編程BIO理論基礎與性能分析

    簡單認識BIO BIO在網絡編程中指的是同步阻塞的網絡模型(Blocking IO),Java中BIO一般就是我們使用java.io包下提供的一些用來實現網絡編程的方法。 單線程代碼演示 服務端 客戶端 一段非常簡單的服務端與客戶端的demo,服務端啟動監聽9090端口,并且當有客戶端到來時開始無限循環讀取客戶端發送的請求數據。 客戶端通過從System.in中獲取數據并推送到服務端。 啟動服務端...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡