我用套接字创建了一个Java服务器,如何打印到所有套接字?

Kei*_*vis 8 java sockets serversocket printwriter

我已经尝试了一段时间,我希望多个客户端同时接收多个输入.
有一个问题,如果一个客户端说'print2all Hi',我希望服务器向所有客户打印"Hi".
我知道如何处理它来打印它,只是打印到所有客户端是问题.

这是我到目前为止所拥有的.
服务器

try{
    try{
        server = new ServerSocket(25565);
    } catch (Exception e){
        e.printStackTrace();
    }
    while (isListening){
        new SocketThread(server.accept()).start();
    }
    server.close();
} catch (Exception e){
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

SocketThread

try {
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    String inputLine, outputLine;
    Processor kkp = new Processor();
    out.println("Hi!");

    while ((inputLine = in.readLine()) != null) {
        outputLine = kkp.Proccess(inputLine,this.socket);
        out.println(outputLine);
    }
    out.close();
    in.close();
    socket.close();

} catch (IOException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

客户

            Processor p = new Processor();
            socket = new Socket("localhost",25565);
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));                
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            String fromServer;
            String fromUser;
            out.println("print2all Hi")            
            socket.close();
Run Code Online (Sandbox Code Playgroud)

Tom*_*icz 6

首先,您需要跟踪所有连接的客户端:

final List<SocketThread> clients = new ArrayList<>();

while (isListening){
    SocketThread client = new SocketThread(server.accept()).start();
    clients.add(client);
}
Run Code Online (Sandbox Code Playgroud)

如果一个客户端收到"print2all Hi"它,那么拥有这样的列表只是遍历所有clients并向每个客户端发送消息.要做到这一点,你很可能必须公开一些方法SocketThread来访问客户端套接字.这意味着您必须将out变量更改为字段.

替代方法是保留客户端套接字列表.但这严重破坏了封装.如果直接暴露套接字,您可能会遇到令人讨厌的IO /线程安全问题.最好将它们隐藏在某些API(如SocketThread方法)后面并在内部正确进行同步.