標籤:soc 功能 啟動 body 客戶 用戶端串連 err strong 完成後
本文講解如何用java實現網路通訊,是一個非常簡單的例子,我比較喜歡能夠立馬看到結果,所以先上代碼再講解具體細節。
服務端:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class Server { // 搭建伺服器端 public static void main(String[] args) throws IOException { Server server = new Server(); //建立一個伺服器,即Server server.oneServer(); } public void oneServer() { try { ServerSocket server = null; server = new ServerSocket(5209); System.out.println("伺服器啟動成功"); System.out.println("等待用戶端串連"); // 指定綁定的連接埠,並監聽此連接埠。 Socket socket = server.accept(); System.out.println("監聽到用戶端的串連"); System.out.println("串連成功"); //調用accept()方法開始監聽連接埠,等待用戶端的串連 String line; //儲存對方傳過來的資料 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 從socket對象中取出對方傳過來的資料 PrintWriter writer=new PrintWriter(socket.getOutputStream()); // 向socket總寫如要傳給對方的資料 while ((line = in.readLine()) != null) { writer.println(line+" deal by servet"); // 向用戶端輸出該字串 writer.flush(); // 重新整理輸出資料流,使Client馬上收到該字串 System.out.println("Client:" + line); // 從Client讀入一字串,並列印到標準輸出上 } // 繼續迴圈 // 關閉資源 writer.close(); //關閉Socket輸出資料流 in.close(); // 關閉Socket輸入資料流 socket.close(); // 關閉Socket server.close(); // 關閉server } catch (Exception e) {// 出錯,列印出錯資訊 System.out.println("Error." + e); } }}
用戶端:
import java.net.Socket;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.InetAddress;import java.net.Socket;import java.net.URL;public class Client { // 搭建用戶端 public static void main(String[] args) throws IOException { try { // 建立用戶端Socket,指定伺服器位址和連接埠 // Socket socket=new Socket("127.0.0.1",5200); System.out.println("用戶端啟動成功"); Socket socket = new Socket("192.168.69.183", 5209); System.out.println("向服務端5209連接埠請求成功"); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 由系統標準輸入裝置讀入資料,該資料通過writer寫到對方的socket中 PrintWriter write = new PrintWriter(socket.getOutputStream()); // 向socket總寫入要傳給對方的資料 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 從socket對象中取出對方傳過來的資料 String readline; readline = br.readLine(); // 從系統標準輸入讀入一字串 while (!readline.equals("end")) { // 若從標準輸入讀入的字串為 "end"則停止迴圈 write.println(readline); // 將從系統標準輸入讀入的字串輸出到對方的socket中 write.flush(); //列印出對方傳過來的資料 System.out.println("Server:" + in.readLine()); // 從Server讀入一字串,並列印到標準輸出上 readline = br.readLine(); // 從系統標準輸入讀入一字串 } // 繼續迴圈 //關閉資源 write.close(); // 關閉Socket輸出資料流 // in.close(); // 關閉Socket輸入資料流 socket.close(); // 關閉Socket br.close(); } catch (Exception e) { System.out.println("can not listen to:" + e);// 出錯,列印出錯資訊 } }}
這裡我們要實現的功能是用戶端從鍵盤輸入一個字串,發送給服務端,服務端處理(原字串後加上“deal by servet”)完成後返回給用戶端。我用的是eclipse,最好開兩個eclipse一個跑用戶端一個跑服務端。先開服務端,再開用戶端(順序不能錯),用戶端輸入hello,服務端返回hello deal by server:
看到成果了那麼可以分析一下整個通訊過程。
先放一個socket通訊模型:
三部分:建立串連,開始通訊,中斷連線。
建立串連:我們稍微思考一下就可以知道建立串連的過程要先存在服務端server,然後用戶端client才能找,所以要先啟動服務端。可能我們認為服務端或者說伺服器是一個很神秘的東西,其實不是,看我們這個例子中服務端的代碼:
new一個伺服器,但是這個伺服器new出來之後什麼都沒做,我們需要調用他裡面的方法讓這個伺服器可以運行。所以寫了一個oneServer方法,伺服器對象調用這個方法開始運行。
那麼伺服器啟動並執行時候都幹了什麼呢?看上面的模型,伺服器運行做三件事:串連,傳送資料,斷開。
看oneServer中的代碼,先是建立了一個ServerSocket的對象,這個對象有一個參數5209:
ServerSocket是專門用來建立伺服器對象的,其中的參數5209表示這個伺服器可以通過5209連接埠被用戶端串連,即5209連接埠與建立的這個ServerSocket對象綁定了。但是這個綁定只是在伺服器與連接埠之間建立了一個通道,我們還要能夠讓伺服器知道有資料從外面到了這個連接埠,並且因為連接埠不能存放資料所以需要一個socket來暫時存放資料。所以有了下面的監聽:
到這裡,伺服器已經啟動並運行了,用戶端可以串連了。
這時候啟動用戶端,用戶端通過socket串連到服務端,指定ip和連接埠號碼:
用戶端運行到這裡表示與服務端的串連已經完成:
串連成功之後就是傳送資料,用戶端建立三個對象:
br從鍵盤讀入要傳送的資料,write向socket寫入要傳給服務端的資料,in從socket對象中取出服務端返回的資料。
服務端建立兩個對象:
write向socket寫入要傳回給用戶端的資料,in從socket對象中取出用戶端傳來的資料。
到這裡資料轉送的準備工作完成,接下來就是資料轉送。
用戶端從鍵盤讀入一個字串(hello),通過br讀入:
然後用戶端判斷是否為end,不是end就繼續。通過用戶端的write,將readline中的內容寫到對方(服務端)的socket中,同時使用write的flush方法通知服務端,讓服務端立馬知道有資料了:
服務端監聽到連接埠有資料之後,通過in接收用戶端發過來的資料,並轉成字串,然後處理這個字串(加上deal by server)並寫到用戶端的socket中,同時也調用writer的flush方法通知用戶端:
運行到這裡,服務端已經處理並返回了用戶端發過來的資料,在用戶端的控制台中可以看到返回的資料:
服務端在自己的控制台中列印出用戶端發過來的資料:
整個傳送流程結束,如果輸入的字串是end,那麼就會跳出while迴圈,用戶端服務端各自關閉資源:
到這裡,整個過程結束。
再文字說明一下整個流程,伺服器啟動——伺服器建立socket並監聽——用戶端啟動——用戶端建立socket串連服務端——串連完成——用戶端輸入資料並寫到服務端的socket傳送給服務端——服務端接收到用戶端傳來的資料——對資料進行處理——處理完畢放到用戶端的socket中——用戶端拿取自己socket中的資料——列印——雙方中斷連線。
java的socket通訊