前言
Java網路程式設計之Socket套接字,Socket套接字使用TCP提供了兩臺計算機之間的通訊機制
TCP(英語:Transmission Control Protocol,傳輸控制協議) 是一種面向連線的、可靠的、基於位元組流的傳輸層通訊協議,TCP 層是位於 IP 層之上,應用層之下的中間層。TCP 保障了兩個應用程式之間的可靠通訊。通常用於網際網路協議,被稱 TCP / IP
本文記錄Java的Socket通訊簡單例項
服務端
package cn.huanzi.qch.util; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Socket服務端 */ public class SocketServer { public static void main(String[] args) throws Exception{ //服務端在20006埠監聽客戶端請求的TCP連線 ServerSocket server = new ServerSocket(20086); Socket client; System.out.println("服務端啟動成功!"); //如果使用多執行緒,那就需要執行緒池,防止併發過高時建立過多執行緒耗盡資源 ExecutorService threadPool = Executors.newFixedThreadPool(10); while (true) { //等待客戶端的連線,如果沒有獲取連線 client = server.accept(); //為每個客戶端連線開啟一個執行緒 threadPool.submit(new ServerThread(client)); } } } /** * 與客戶端連線操作非同步執行緒 */ class ServerThread implements Runnable { //socket連線 private final Socket client; public ServerThread(Socket client){ this.client = client; } @Override public void run() { try{ System.out.println("與客戶端["+client.getInetAddress()+":"+client.getPort()+"]連線成功!"); //獲取Socket的輸出流,用來向客戶端傳送資料 PrintStream out = new PrintStream(client.getOutputStream()); //獲取Socket的輸入流,用來接收從客戶端傳送過來的資料 BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8)); boolean flag =true; while(flag){ //接收從客戶端傳送過來的資料 String msg = buf.readLine(); //約定:通過約定符號'exit'通知服務端關閉與客戶端的連線 if("exit".equals(msg)){ flag = false; }else{ //將接收到的字串前面加上echo,傳送到對應的客戶端 out.println("echo:"+msg); } System.out.println("收到客戶端["+client.getInetAddress()+":"+client.getPort()+"]訊息:"+msg); } System.out.println("與客戶端["+client.getInetAddress()+":"+client.getPort()+"]斷開連線..."); out.close(); buf.close(); client.close(); }catch(Exception e){ System.err.println("Socket連線異常..."); e.printStackTrace(); } } }
客戶端
package cn.huanzi.qch.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.SocketTimeoutException; import java.nio.charset.StandardCharsets; /** * Socket客戶端 */ public class SocketClient { //地址 private static final String host = "127.0.0.1"; //埠 private static final int port = 20086; //Socket連線 private static Socket client; //Socket的輸出流,用來傳送資料到服務端 private static PrintStream out; //Socket的輸入流,用來接收從服務端傳送過來的資料 private static BufferedReader buf; /** * 初始化Socket連線 */ private static void init() throws IOException { //客戶端請求與 host 在 port 埠建立TCP連線 client = new Socket(host, port); //獲取Socket的輸出流 out = new PrintStream(client.getOutputStream()); //獲取Socket的輸入流 buf = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8)); } /** * 傳送訊息 */ private static void sendMsg(String msg) throws IOException { try{ //傳送資料到服務端 out.println(msg); }catch (Exception e){ //列印日誌,並重連Socket System.err.println("Socket連線異常,正在重新連線..."); e.printStackTrace(); init(); //重新傳送資料資料到服務端 out.println(msg); } //等待服務端響應 try{ String echo = buf.readLine(); System.out.println("收到服務端回應:"+echo); }catch(SocketTimeoutException e){ System.err.println("服務端響應超時..."); e.printStackTrace(); } catch (IOException e) { System.err.println("服務端響應異常..."); e.printStackTrace(); } } /** * 關閉Socket連線 * 約定:通過約定符號'exit'通知服務端關閉與客戶端的連線 */ private static void close() throws IOException { //通知服務端結束與客戶端的連線非同步執行緒 out.println("exit"); out.close(); buf.close(); client.close(); } public static void main(String[] args) throws IOException, InterruptedException { init(); for (int i = 1; i <= 5; i++) { sendMsg("你好,我是訊息"+i); Thread.sleep(2000);//休眠 } close(); } }
效果
先執行服務端,再執行客戶端
客戶端
服務端
後記
為了減少傳輸資料的大小,可以通過約定報文格式,傳輸16進位制資料,例如:OxFF 01 3A 4D
Java的Socket通訊簡單例項暫時先記錄到這,後續再進行補充