同步阻塞式IO(BIO)--學習筆記
阿新 • • 發佈:2019-01-24
執行緒模型如下:
採用BIO模式的socket服務端,通常由獨立的Acceptor執行緒負責監聽客戶端連線,如果沒有客戶端傳送連線,Accpetor 會一直處於阻塞狀態。在接收到客戶端請求後,建立一個執行緒來處理該請求,處理完成後可以通過輸出流回應客戶端,然後執行緒銷燬。執行緒和客戶端併發數相等。完全是一次請求一次應答模式。
如果你有少量的連線使用非常高的頻寬,一次傳送大量的資料,也許典型的BIO伺服器實現可能非常契合。對於高併發訪問,每次訪問建立一個新的執行緒處理顯然不可行。
以下是javaSocket 實現程式碼:
伺服器端全部測試程式碼:
package bioFrame.server; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import bioFrame.server.handler.StringServerHandler; /** * 同步阻塞式IO,為每個連結建立一個執行緒 * * @author Mercy * */ public class ServerMain { public static int port = 9001;//預設監聽埠 public static void main(String[] args){ System.out.println("Server start……"); ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); while(true){ Socket socket = serverSocket.accept(); new Thread(new StringServerHandler(socket)).start(); } } catch (IOException e) { e.printStackTrace(); } finally { if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
StringServerHandler 用來解析收到的文字內容
package bioFrame.server.handler; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; /** * 用於接收客戶端發來的文字訊息,輸出到控制檯,並返回給客戶端一個時間戳 * @author Mercy * */ public class StringServerHandler implements Runnable{ private Socket socket; public StringServerHandler(Socket socket) { this.socket = socket; } @Override public void run() { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream())); StringBuffer sb = new StringBuffer(); while(br.ready()){//判斷是否已準備好被讀取 sb.append(br.readLine()); } // String content = br.readLine(); // while(content != null){ // sb.append(content); // content = br.readLine();//這裡會阻塞? // } System.out.println("Server recive :" + sb.toString()); PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.print(String.valueOf(System.currentTimeMillis())); pw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if(br != null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } br = null; } if(socket != null){ if(!socket.isClosed()){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } socket = null; } } } } }
socket客戶端測試程式碼如下:
package bioFrame.client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; /** * 同步阻塞式IO,傳送文字內容給伺服器,讀取伺服器響應,並列印結果 * @author Mercy * */ public class ClientMain { /** * 要連線的伺服器埠 */ private static int port = 9001; private static String ip = "127.0.0.1"; public static void main(String[] args){ Socket socket = null; try { socket = new Socket(ip,port); PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.println("這裡是第一行內容"); pw.println("這裡是第二行內容"); pw.flush(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("client recive :" + bufferedReader.readLine()); pw.close(); bufferedReader.close(); } catch (Exception e) { e.printStackTrace(); } finally { if(socket != null){ if(!socket.isClosed()){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } socket = null; } } } } }