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 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-8
import socket
import threading

HOST = "localhost"
PORT = 30000

sock = 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-8
import socket
import threading

HOST = "localhost"
PORT = 30000

sock = 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 服務器向指定的客戶端發消息,網上給的資源不多,大多是關於服務器群發. 這里給出了具體解決方案,並通過實例證實了該方案的可行性.

 

有時看的資料越多,越不明白.這並總是好事. 

這個時候就需要靜下來理理思路,然后針對具體的解決方案,編程實現. 

實踐才是檢驗真理的唯一標准,設計代碼的時候你就離成功又近了一步.

參考文獻

  1. java socket編程中,如何讓服務器主動向指定ip地址的客戶端發送信息
  2. socket 服務器給指定的客戶端發消息該怎么處理
  3. socket 服務器給指定的客戶端發消息該怎么處理

--------------------- 

作者:Deen12520 

來源:CSDN 

原文:https://blog.csdn.net/dingding_12345/article/details/72790839 

版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM