首页 > 解决方案 > 有没有办法仅在 Java 套接字中从服务器向一个客户端发送消息?

问题描述

我正在尝试构建服务器和客户端应用程序。客户端将登录数据(电子邮件和密码)发送到服务器。然后服务器将响应客户端登录数据是否正确。问题是我希望服务器只响应仅发送登录数据的客户端。请注意,我想保持类方法的通用性,以便可以在 GUI (Javafx) 控制器类上使用它们。我怎样才能做到这一点?

public class ServerConnector extends Thread{

    public static final int PORT_NO = 5005;
    private ServerSocket serverSocket;

    /**
     * Starts the server
     */
    public void startServer() {
       this.start();
    }

    @Override
    public void run() {
       Socket clientSocket;
        try {
            serverSocket = new ServerSocket(PORT_NO);
            while (true) {
                clientSocket = serverSocket.accept();
                new ClientHandler(clientSocket);
            }

        } catch (IOException ex) {
            ex.printStackTrace();
        } 
    }
}
public class ClientHandler extends Thread {

    private DataInputStream dis;
    private PrintStream ps;
    private Socket clientSocket;


    public static Vector<ClientHandler> clientThreads = new Vector<ClientHandler>();

    public ClientHandler(Socket s) {
        try {         
            this.clientSocket = s;
            dis = new DataInputStream(clientSocket.getInputStream());
            ps = new PrintStream(clientSocket.getOutputStream());
            clientThreads.add(this);
            start();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void printMsg(String msg) {
        System.out.println(msg);
    }

    @Override
    public void run() {
        while (true) {

            try {
                String str = dis.readLine();
                if(str.equals("JavaTODO_ClientFINISH"))
                {
                    System.out.println("JavaTODO_ClientFINISH");
                    clientThreads.remove(this);
                    this.stop();
                }
                else
                {
                    System.out.println(str);
                }
            } catch (IOException ex) {
               ex.printStackTrace();
            } 
        }
    }

    /**
     * sends message to all clients connected to the server
     *
     * @param msg to be sent
     */
    public static void sendToAll(String msg) {
        for (ClientHandler ch : clientThreads) {
            ch.ps.println(msg);
        }
    }

    /**
     * sends message to one client
     *
     * @param msg to be sent to one client
     */
    public void sendToOneClient(String msg,int index) {     
            ps.println(msg);
            //clientThreads.get(index).ps.println(msg);
            //psStatic.println(msg);    
    }

    /**
     * close the open connection and release resources
     */
    public void closeConnection() {
        try {
            dis.close();
            ps.close();
            clientSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

标签: javaserversocket

解决方案


只需添加一种 cookie。cookie 只不过是与请求一起发送的字符串。

 cookie=login_id:33384adeg73eg344;

只有当人们成功登录时,cookie id 才会被提供给他们,并且他们会在发送到服务器以验证他们身份的每个后续请求中将其发送回。

它是如何工作的一个小例子。

流程图

如果您查看普通的 http 标头,您会看到许多元数据,这些元数据对于服务器了解如何处理数据、请求者期望/接受的数据、使用什么语言、cookie 是什么等很有用。您可以考虑在您的套接字处理程序中编写这样一个简单的东西,以便能够翻译客户“想要”的内容

accept: application/json, text/javascript, */*; q=0.01
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: no-cache
content-length: 489
content-type: application/x-www-form-urlencoded; charset=UTF-8
cookie: id=foobar
origin: https://stackoverflow.com

但我建议你也考虑一下安全性。这些传输都容易被网络嗅探器等拦截,并且可以被欺骗。理想情况下,您应该使用支持安全连接的安全网络传输库,如果您坚持编写自己的实现,至少是 SSLServerSocket 。


推荐阅读