資料:慕課網
第二章:手動搭建I/O網絡通信框架2:BIO編程模型實現群聊
第三章:手動搭建I/O網絡通信框架3:NIO編程模型,升級改造聊天室
第四章:手動搭建I/O網絡通信框架4:AIO編程模型,聊天室終極改造
這個基礎項目會作為BIO、NIO、AIO的一個前提,后面會有數篇博客會基於這個小項目利用BIO、NIO、AIO進行改造升級。
簡單的說一下io,了解的直接跳過看代碼吧:IO常見的使用場景就是網絡通信或讀取文件等方面。IO流分為字節流和字符流。字節即Byte,包含八位二進制數,一個二進制數就是1bit,中文名稱叫位。字符即一個字母或者一個漢字。一個字母由一個字節組成,而漢字根據編碼不同由2個或者3個組成。Java.io包如下:詳細的API可自行查閱資料
Socket定義:套接字(socket)是一個抽象層,應用程序可以通過它發送或接收數據,可對其進行像對文件一樣的打開、讀寫和關閉等操作。套接字允許應用程序將I/O插入到網絡中,並與網絡中的其他應用程序進行通信。網絡套接字是IP地址與端口的組合。
可以理解為兩台機器或進程間進行網絡通信的端點,這個端點包含IP地址和端口號。
Socket和ServerSocket區別就如其名字一樣,簡單地說ServerSocket作用在服務端,用以監聽客戶端的請求。Socket作用在客戶端和服務端,用以發送接收消息。但是就像上面說的,它們都要包含一個IP地址和端口號。
Socket和ServerSocket實戰:
首先創建一個最普通的Java項目。然后創建兩個類,Server和Client。其代碼和注釋如下,仔細看下注釋和代碼,還是比較簡單的
服務器只能為一個客戶端服務,一旦監聽到客戶端的請求,就會一直被這個客戶端占用。
public class Client { public static void main(String[] args) { //這是服務端的IP和端口 final String DEFAULT_SERVER_HOST = "127.0.0.1"; final int DEFAULT_SERVER_PORT = 8888; //創建Socket try (Socket socket = new Socket(DEFAULT_SERVER_HOST, DEFAULT_SERVER_PORT)) { //接收消息 BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); //發送消息 BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(socket.getOutputStream()) ); //獲取用戶輸入的消息 BufferedReader userReader = new BufferedReader( new InputStreamReader(System.in) ); String msg = null; //循環的話客戶端就可以一直輸入消息,不然執行完try catch會自動釋放資源,也就是斷開連接 while (true) { String input = userReader.readLine(); //寫入客戶端要發送的消息。因為服務端用readLine獲取消息,其以\n為終點,所以要在消息最后加上\n writer.write(input + "\n"); writer.flush(); msg = reader.readLine(); System.out.println(msg); //如果客戶端輸入quit就可以跳出循環、斷開連接了 if(input.equals("quit")){ break; } } } catch (IOException e) { e.printStackTrace(); } } }
public class Server { public static void main(String[] args) { final int DEFAULT_PORT = 8888; //創建ServerSocket監聽8888端口 try (ServerSocket serverSocket = new ServerSocket(DEFAULT_PORT)) { System.out.println("ServerSocket Start,The Port is:" + DEFAULT_PORT); while (true) {//不停地監聽該端口 //阻塞式的監聽,如果沒有客戶端請求就一直停留在這里 Socket socket = serverSocket.accept(); System.out.println("Client[" + socket.getPort() + "]Online"); //接收消息 BufferedReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream()) ); //發送消息 BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(socket.getOutputStream()) ); String msg = null; while ((msg = reader.readLine()) != null) { System.out.println("Client[" + socket.getPort() + "]:" + msg); //寫入服務端要發送的消息 writer.write("Server:" + msg + "\n"); writer.flush(); //如果客戶端的消息是quit代表他退出了,並跳出循環,不用再接收他的消息了。如果客戶端再次連接就會重新上線 if (msg.equals("quit")) { System.out.println("Client[" + socket.getPort() + "]:Offline"); break; } } } } catch (IOException e) { e.printStackTrace(); } } }
然后打開兩個命令終端,通過javac編譯后,一個運行Server代表服務器,一個運行Client代表客戶端。
下一篇:基於BIO進行升級改造,打造群聊聊天室。