實現socket的服務和客戶端通訊
阿新 • • 發佈:2018-11-02
對學習過程中自己敲的一些關於socket有關的程式碼做了個簡單總結,在這分享一下,給有需要的同學借鑑一下。
什麼是socket?
網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個連線的一端稱為一個socket。 建立網路通訊連線至少要一對埠號(socket)。socket本質是程式設計介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式設計師做網路開發所用的介面,這就是Socket程式設計介面;HTTP是轎車,提供了封裝或者顯示資料的具體形式;Socket是發動機,提供了網路通訊的能力。 Socket的英文原義是“孔”或“插座”。作為BSD UNIX的程序通訊機制,取後一種意思。通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控制代碼,可以用來實現不同虛擬機器或不同計算機之間的通訊。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並繫結到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原義那樣,像一個多孔插座。一臺主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。 Java就給我們提供了socket,我們只要會使用就可以了,接下來為大家介紹一個簡單的socket小例子,完成socket服務和客戶端間的通訊。 這是我們socket小例子的一個簡單架構,由服務端、客戶端、執行緒工作業務邏輯、資料獲取類組成。
首先我們先來完成socket服務端的程式碼開發。
在服務端的main方法裡,我們將socketserver物件設定成持久的,並綁定於本機的8899埠上,去接收客戶端的socket連線。
package com.wenbing.socket; import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ServerSocket; import java.net.Socket; public class ServiceServer { publicstatic void main(String[] args) throws Exception{ // 建立一個serversocket,繫結到本機的8899埠上 ServerSocket server = new ServerSocket(); server.bind(new InetSocketAddress("localhost", 8899)); // 接收客戶端的連線;accept是一個阻塞方法,會一直等待,到有客戶端請求連線才返回 while (true) { Socket socket= server.accept(); // 每個socket請求都給一個執行緒來處理 new Thread(new ServiceServerTask(socket)).start(); } } }
我們定義一個服務端處理客戶端請求過來的資料處理執行緒工作類,讓每個請求來的socket都由每一個執行緒去執行業務邏輯,ServiceServerTask類實行Runnable介面。
package com.wenbing.socket; import java.io.*; import java.net.Socket; public class ServiceServerTask implements Runnable { Socket socket; InputStream inputStream = null; OutputStream outputStream = null; public ServiceServerTask(Socket socket) { this.socket = socket; } // 業務邏輯,跟客戶端進行資料互動 @Override public void run() { try { // 從socket連線中獲取到與client之間的網路通訊輸入流 inputStream = socket.getInputStream(); // 從socket連線中獲取到與client之間的網路通訊輸出流 outputStream = socket.getOutputStream(); // BufferedReader讀取資料是一個字元一個字元讀取,遇到回車即停止 BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); // 從網路通訊輸入流中讀取客戶端傳送過來的資料,讀取一行,遇到回車即結束 // 注意:socketinputstream的讀資料的方法是阻塞的 //讀取很多行資料,用while迴圈讀 // String line = ""; // String param = ""; // while (( line = br.readLine()) != null) { // param = br.readLine(); // System.out.println(param); // } String param = br.readLine(); System.out.println(param); GetDataServiceImpl getDataService = new GetDataServiceImpl(); String result = getDataService.getData(param); // 將呼叫結果寫到socket的輸出流中,以傳送給客戶端 PrintWriter printWriter = new PrintWriter(outputStream); printWriter.println(result); printWriter.flush(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 關流,現在是在每個執行緒裡 inputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
處理資料的方法。
package com.wenbing.socket; public class GetDataServiceImpl { public String getData(String param) { return "OK-" + param; } }
接下來就是socket客戶端了。客戶端和服務端程式碼基本相同。
package com.wenbing.socket; import java.io.*; import java.net.Socket; public class ServiceClient { public static void main(String[] args) throws Exception { // 向伺服器發出請求建立連線 Socket socket = new Socket("localhost", 8899); // 從socket中獲取輸出流 InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream(); PrintWriter printWriter = new PrintWriter(outputStream); printWriter.println("hello"); printWriter.flush(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String result = bufferedReader.readLine(); System.out.println(result); inputStream.close(); outputStream.close(); socket.close(); } }
簡單的socket小例子,送給java小白們。
紙上得來終覺淺,絕知此事要躬行,一定要跟著敲一敲才更容易理解哦。