java網路程式設計:9、基於TCP的socket程式設計(二)伺服器端迴圈監聽接收多個客戶端_多執行緒伺服器程式
宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!!
文章目錄
上篇講了基於tcp的程式設計的一些基礎知識,還寫了一個簡單的socket通訊的程式碼,大家如需瞭解可參考 java網路程式設計:8、基於TCP的socket程式設計(一)簡單的socket通訊_一個客戶端,這篇較上篇稍微深入點,本來上篇就要搞定的,因為是整理知識、整理程式碼,所以自己不希望部落格篇幅太長,不方便以後自己的查閱,所以拖到這篇來寫、來記錄!
一、核心程式碼編寫
伺服器端迴圈監聽接收多個客戶端_多執行緒伺服器程式
1、伺服器端程式的編寫
public class Myserver extends Thread{ public static void main(String[] args) { server(); } private Socket s; public Myserver(Socket s) { this.s = s; } @Override public void run() { try { // 可以利用套接字獲取輸出流、輸入流 OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); // 利用輸出流向客戶端傳送資料 // getBytes將字串轉換成位元組陣列 os.write("Hello,welcome you,client!".getBytes()); // 利用輸入流從網路上讀取資料 // 建立位元組陣列 byte[] buf = new byte[100]; // 將資料讀取到buf位元組陣列當中,它會返回實際讀取的位元組數 int len = is.read(buf); // 將我們讀取的資料打印出來 System.out.println(new String(buf, 0, len)); // 完成通訊之後,我們可以將輸出流、輸入流、套接字、伺服器端的套接字都關閉 os.close(); is.close(); s.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 伺服器端程式的編寫 */ public static void server() { try { // 建立伺服器端套接字,繫結到6000的埠上 ServerSocket ss = new ServerSocket(6000); //當前為一個客戶服務,要為多個客戶同時服務加while迴圈監聽客戶端請求 while (true) { // 呼叫accept方法就會阻塞,直到客戶端有連線請求到來的時候。 // 它會返回一個套接字,然後就可以利用這個套接字與客戶端進行資料通訊。 Socket s = ss.accept(); //一旦有一個連線請求到來,接收連線請求,返回套接字。 //然後建立啟動一個新的執行緒,將套接字傳遞給執行緒,為客戶端進行服務 //Run執行完畢,當前執行緒也就終止了 new Myserver(s).start(); } //ss.close(); } catch (Exception ex) { ex.printStackTrace(); } } }
2、客戶端程式的編寫
/** * 客戶端程式的編寫 */ public static void client() { try { // 建立一個客戶端的套接字,指定一個ip地址和埠。 // 讓它連線到我們伺服器端上,在這個埠上等待連線的伺服器程序 // ip地址:你可以指定主機名,或者指定ip地址,讓它直接返回。 // 我們在編寫程式的時候,可能沒有兩臺機器,沒有關係,我們可以在一臺機器上, // 讓我們服務端程式和客戶端程式,通過網路進行通訊。 // 那麼我們可以獲取本地的ip地址,它有三種方式: // InetAddress.getByName("localhost") // InetAddress.getByName("127.0.0.1")是我們本地的迴路地址 // InetAddress.getByName(null)它也可以返回本地的IP地址 //那麼這三種方式,即使這我們的機器上沒有網絡卡,也沒有關係。 //那麼作為一臺pc機,它都會有一個"127.0.0.1"作為本地的一個迴路地址,那麼我們用這個地址, //就可以測試我們的網路程式。 //注:你在客戶端傳送連線請求的埠號,和伺服器端等待連線的埠號一定要一致。 //這就好像你打電話一樣,那麼我的分機號是6000,那麼你打過來的時候你轉這個分機號,你也要轉6000 //才能夠和我進行通訊,你不能說你隨便轉個分機號,你想轉5000和我進行通訊,那是不可能的。 Socket s = new Socket(InetAddress.getByName("localhost"), 6000); // 可以利用套接字獲取輸出流、輸入流 OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); //輸入流向伺服器端讀取資料 byte[] buf = new byte[100]; int len = is.read(buf); System.out.println(new String(buf, 0, len)); //輸出流向伺服器端傳送資料 os.write("Hello,this is zhangsan".getBytes()); //完成通訊之後,我們可以將輸出流、輸入流、套接字都關閉 os.close(); is.close(); s.close(); } catch (Exception ex) { ex.printStackTrace(); } }
3、測試列印輸出
首先我們執行伺服器端程式,因為加了迴圈所以伺服器一直在監聽
執行客戶端程式,它連上伺服器端程式併發送訊息,伺服器端收到訊息,如下圖:
同時伺服器端,給客戶端 “zhangsan” 傳送訊息,如下圖:
然後我們模擬多個客戶端:
把客戶端程式語句 os.write("Hello,this is zhangsan".getBytes()); 改成 os.write("Hello,this is lisi".getBytes());
再次執行客戶端程式,同樣可以連線到伺服器端程式併發送訊息,伺服器端收到訊息,如下圖:
同時伺服器端,給客戶端 “lisi” 傳送訊息,如下圖:
二、系列文章(java網路程式設計)
java網路程式設計:1、計算機網路?網路通訊的組成?什麼是ip、協議、埠號?
java網路程式設計:2、IP地址、協議、網路狀況、網路異質性問題的解決
java網路程式設計:6、TCP/IP模型、TCP/IP模型與OSI參考模型的對應關係
java網路程式設計:8、基於TCP的socket程式設計(一)簡單的socket通訊_一個客戶端
java網路程式設計:9、基於TCP的socket程式設計(二)伺服器端迴圈監聽接收多個客戶端_多執行緒伺服器程式
java網路程式設計:10、基於TCP的socket程式設計(三)緩衝流、flush方法、關閉流
java網路程式設計:11、基於UDP的socket程式設計(一)理論、基本步驟
java網路程式設計:12、基於UDP的socket程式設計(二)程式碼通訊-簡單例項
java網路程式設計:13、基於UDP的socket程式設計(三)實現相互發送接收訊息