socket 服务器向指定的客户端发消息

一.需求

需求如题. 当多个客户端连接服务器时,服务器如何给指定的客户端发送消息.

二.解决方案

核心思想: 在服务器端,需保存不同客户端的socket列表及客户端相关信息.
socket含有发送方和接收方的ip和端口号,所以通过socket就能向指定的客户端发送消息.

经查阅资料,得到如下解决方案:

  1. 用户连接时,立即向服务器发送自己的唯一ID,服务器端将ID和对应的socket用map存储. 向客户端发送消息时,就可以通过ID,找到对应的socket,然后向其发送消息.
  2. 如果客户端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 服务器给指定的客户端发消息该怎么处理
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值