socket 伺服器向指定的用戶端發訊息,socket訊息
一.需求
需求如題. 當多個用戶端串連伺服器時,伺服器如何給指定的用戶端發送訊息.
二.解決方案
核心思想: 在伺服器端,需儲存不同用戶端的socket列表及用戶端相關資訊.
socket含有發送方和接收方的ip和連接埠號碼,所以通過socket就能向指定的用戶端發送訊息.
經查閱資料,得到如下解決方案:
三.實踐
說明:採用第一種解決方案,類比伺服器向指定的用戶端發送訊息.
服務端迴圈監聽,第一個伺服器進來,向其發送其自身序號,第二個進來,遍曆socke列表,向列表中的每一個用戶端發送其對應的序號,從而達到伺服器向指定用戶端發送訊息的功能.
伺服器端
package server;import java.io.*;import java.net.*;import java.util.HashMap;/** * 主函數,實現伺服器向指定用戶端發送訊息的功能. * 用戶端用python書寫 * @author dingding * */public class Run { private final static int PORT = 30000; public static HashMap<String, Socket> socketList = new HashMap<>(); public static String channelToken; //socket 令牌 private static BufferedReader bufferedReader; public static void main(String[] args) { try { ServerSocket server = new ServerSocket(PORT); System.out.println("server is listenning..."); while(true){//不斷迴圈隨時等待新的用戶端接入伺服器 Socket clientSocket = server.accept(); bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); channelToken = bufferedReader.readLine(); socketList.put(channelToken,clientSocket); //儲存會話ID和socket //System.out.println(socketList.get(channelToken)); //System.out.println(socketList); new ServerThread(clientSocket,socketList); } } catch (IOException e) { e.printStackTrace(); } }}
package server;import java.io.*;import java.net.*;import java.util.*;public class ServerThread extends Thread{ private Socket client; private PrintWriter out; private HashMap<String, Socket> clientList = new HashMap<>(); public ServerThread(Socket socket,HashMap<String, Socket> socketList) throws IOException{ super(); client = socket; clientList = socketList; start(); } @Override public void run(){ Socket socket; System.out.println("Client: "+getName()+" come in..."); //每當用戶端串連上,就向相應的用戶端進行回應 Iterator<HashMap.Entry<String, Socket>> entries = clientList.entrySet().iterator(); while (entries.hasNext()){ HashMap.Entry<String, Socket> entry = entries.next(); System.out.println(entry.getKey()); if (!String.valueOf(entry.getKey()).equals("")) { System.out.println(entry.getValue()); System.out.println("-------------"); socket = entry.getValue(); if (socket!=null) { try { out = new PrintWriter(socket.getOutputStream()); //回複client的ID out.println(entry.getKey()); out.flush(); } catch (IOException e) { e.printStackTrace(); } } } } }}
兩個用戶端
用兩個python用戶端來類比情境.
#coding = utf-8import socketimport threadingHOST = "localhost"PORT = 30000sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((HOST, PORT)) def test(): socketID = 'I am 111' sock.sendall((socketID+'\r').encode()) while True: data = sock.recv(1024).decode() print('from line: '+data) sock.close()if __name__ == '__main__': test()
#coding = utf-8import socketimport threadingHOST = "localhost"PORT = 30000sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((HOST, PORT))def test(): socketID = 'I am 000' sock.sendall((socketID+'\r').encode()) while True: data = sock.recv(1024).decode() print('from line: '+data) sock.close()if __name__ == '__main__': test()
四.總結
socket 伺服器向指定的用戶端發訊息,網上給的資源不多,大多是關於伺服器群發. 這裡給出了具體解決方案,並通過執行個體證實了該方案的可行性.
有時看的資料越多,越不明白.這並總是好事.
這個時候就需要靜下來理理思路,然後針對具體的解決方案,編程實現.
實踐才是檢驗真理的唯一標準,設計代碼的時候你就離成功又近了一步.
參考文獻 查看評論