• 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+'
    ').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+'
    ').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 

    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    [bzoj3295][Cqoi2011][动态逆序对] (树套树)
    [bzoj3209][花神的数论题] (数位dp+费马小定理)
    [bzoj1026][SCOI2009][windy数] (数位dp)
    [bzoj4521][Cqoi2016][手机号码] (数位dp+记忆化搜索)
    [bzoj1833][ZJOI2010][count] (数位dp)
    [spoj1182][Sorted Bit Sequence] (数位dp)
    [ural1057][Amount of Degrees] (数位dp+进制模型)
    [hdu3652][B-number] (数位dp)
    【bzoj2523】【CTSC2001】聪明的学生
    友情链接(有的是单向的)
  • 原文地址:https://www.cnblogs.com/Im-Victor/p/11068291.html
Copyright © 2020-2023  润新知