Socket多客戶端通訊
阿新 • • 發佈:2018-11-09
服務端首先構造的是ServerSocket 物件,傳入構造方法中的引數是埠號,同需連線客戶端的埠號一致。接下來通過ServerSocket 物件的accept()方法來獲取Socket物件,此方法被稱為阻塞方法,該一直在執行,等待客戶端傳送的Socket連線請求,若未收到請求,accept()
方法就一直在迴圈執行,始終不返回結果,直到收到請求後,accept()
方法會返回傳送請求的Socket 物件。
/** * Socket多客戶端通訊---服務端 */ public class MultiTalkServer { static int clientNum = 0; public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; try { serverSocket = new ServerSocket(1234); } catch (IOException e) { e.printStackTrace(); } while (listening){ Socket socket = serverSocket.accept(); new ServerThread(socket,clientNum).start(); clientNum++; } serverSocket.close(); } public static class ServerThread extends Thread{ Socket socket = null; int clientNum; private ServerThread(Socket socket,int num){ this.socket = socket; this.clientNum = num+1; } @Override public void run() { try { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); PrintWriter sendStream = new PrintWriter(socket.getOutputStream()); BufferedReader recvStream = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("Client:" + clientNum +" " + recvStream.readLine()); String str = input.readLine(); while (!str.equals("886")){ sendStream.println(str); sendStream.flush(); System.out.println("Server:" + str); System.out.println("Client:" + clientNum+" " + recvStream.readLine()); str = input.readLine(); } sendStream.close(); recvStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
服務端 類中有個靜態成員變數clientNum用來記錄發起請求的客戶端數量,構造ServerSocket物件,在while迴圈方法體建立ServerThread執行緒。相當於main
方法一直在迴圈等待客戶端socket請求,一旦接收到socket請求,就例項化一個執行緒與之互動聊天,執行緒記錄數量加一。
ServerThread的實現,內部維護了socket物件和客戶端數量,run
方法中首先建立了三個流:
- 一個輸入流獲取鍵盤輸入,
- 再用輸出流將資訊傳送給對方網路,
- 最後構造一個輸入流獲取響應的資訊。
接下來判斷鍵盤輸入文字為“886”則停止傳送,聊天結束;否則繼續讀取鍵盤輸入流傳送資訊,最後關閉流和socket的連線。
一個客戶端程式碼如下:多個可相同
public class TalkClient { public static void main(String[] args) { try { Socket socket = new Socket("127.0.0.1",1234); BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); PrintWriter sendStream = new PrintWriter(socket.getOutputStream()); BufferedReader recvStream = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str = input.readLine(); while (!str.equals("886")){ sendStream.println(str); sendStream.flush(); System.out.println("Client: " + str); System.out.println("Server:" + recvStream.readLine()); str = input.readLine(); } sendStream.close(); recvStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
服務端與客戶端的例子很大部分內容相同,只是服務端需要構造一個ServerSocket,通過ServerSocket得到和客戶端連線的Socket物件,得到物件後可以構造輸入、出流進行IO流的讀寫,最後關閉流、Socket即可。