java服务器向客户端发消息_socket 服务器向指定的客户端发消息
一.需求
需求如題. 當多個客戶端連接服務器時,服務器如何給指定的客戶端發送消息.
二.解決方案
核心思想: 在服務器端,需保存不同客戶端的socket列表及客戶端相關信息.
socket含有發送方和接收方的ip和端口號,所以通過socket就能向指定的客戶端發送消息.
經查閱資料,得到如下解決方案:
用戶連接時,立即向服務器發送自己的唯一ID,服務器端將ID和對應的socket用map存儲. 向客戶端發送消息時,就可以通過ID,找到對應的socket,然后向其發送消息.
如果客戶端ip固定,服務器每收到一個Socket都用Map
三.實踐
說明:采用第一種解決方案,模擬服務器向指定的客戶端發送消息.
服務端循環監聽,第一個服務器進來,向其發送其自身序號,第二個進來,遍歷socke列表,向列表中的每一個客戶端發送其對應的序號,從而達到服務器向指定客戶端發送消息的功能.
服務器端
package server;
import java.io.*;
import java.net.*;
import java.util.HashMap;/**
* 主函數,實現服務器向指定客戶端發送消息的功能.
* 客戶端用python書寫
* @author dingding
**/
public classRun {private final static int PORT = 30000;public static HashMap socketList = new HashMap<>();public static String channelToken; //socket 令牌
private staticBufferedReader bufferedReader;public static voidmain(String[] args) {try{
ServerSocket server= newServerSocket(PORT);
System.out.println("server is listenning...");while(true){//不斷循環隨時等待新的客戶端接入服務器
Socket clientSocket =server.accept();
bufferedReader= new BufferedReader(newInputStreamReader(clientSocket.getInputStream()));
channelToken=bufferedReader.readLine();
socketList.put(channelToken,clientSocket);//保存會話ID和socket//System.out.println(socketList.get(channelToken));//System.out.println(socketList);
newServerThread(clientSocket,socketList);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
package server;
import java.io.*;
import java.net.*;
import java.util.*;public classServerThread extends Thread{privateSocket client;private PrintWriter out;private HashMap clientList = new HashMap<>();public ServerThread(Socket socket,HashMapsocketList) throws IOException{
super();
client=socket;
clientList=socketList;
start();
}
@Overridepublic voidrun(){
Socket socket;
System.out.println("Client:"+getName()+"come in...");//每當客戶端連接上,就向相應的客戶端進行回應
Iterator> entries =clientList.entrySet().iterator();while(entries.hasNext()){
HashMap.Entry 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 socket
import threading
HOST= "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())whileTrue:
data= sock.recv(1024).decode()
print('from line:'+data)
sock.close()if __name__ == '__main__':
test()
#coding = utf-8import socket
import threading
HOST= "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())whileTrue:
data= sock.recv(1024).decode()
print('from line:'+data)
sock.close()if __name__ == '__main__':
test()
四.總結
socket 服務器向指定的客戶端發消息,網上給的資源不多,大多是關于服務器群發. 這里給出了具體解決方案,并通過實例證實了該方案的可行性.
有時看的資料越多,越不明白.這并總是好事.
這個時候就需要靜下來理理思路,然后針對具體的解決方案,編程實現.
實踐才是檢驗真理的唯一標準,設計代碼的時候你就離成功又近了一步.
參考文獻
---------------------
作者:Deen12520
來源:CSDN
原文:https://blog.csdn.net/dingding_12345/article/details/72790839
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
總結
以上是生活随笔為你收集整理的java服务器向客户端发消息_socket 服务器向指定的客户端发消息的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: linux内核的I2C子系统详解5——i
 - 下一篇: cocos2dx 圆盘抽奖_cocosc