Java 尝试创建多线程广播服务器-获取IOException

Java 尝试创建多线程广播服务器-获取IOException,java,multithreading,broadcast,ioexception,Java,Multithreading,Broadcast,Ioexception,我正在尝试创建一个多线程广播服务器。我有一个名为ClientHandler的类,它实现了Runnable,该类的每个实例都处理到客户端的单个连接。我的服务器有一个名为connectedClients的HashSet,它存储对类型为Socket的对象的引用。所以我想让这个ClientHandler来处理发送给服务器的消息,但我想让服务器处理发送给客户端的消息,因为我可以轻松地迭代所有客户端,并向每个客户端发送一条消息 我成功地使这台服务器成为一台工作的echo服务器。这意味着,现在当我重新设计它以

我正在尝试创建一个多线程广播服务器。我有一个名为
ClientHandler
的类,它实现了
Runnable
,该类的每个实例都处理到客户端的单个连接。我的服务器有一个名为
connectedClients
HashSet
,它存储对类型为
Socket
的对象的引用。所以我想让这个
ClientHandler
来处理发送给服务器的消息,但我想让服务器处理发送给客户端的消息,因为我可以轻松地迭代所有客户端,并向每个客户端发送一条消息

我成功地使这台服务器成为一台工作的echo服务器。这意味着,现在当我重新设计它以便能够广播消息时,我确信服务器中的所有东西都可以工作,除了这两种方法:

  • ClientHandler的
    run()
    -方法:

    public void run() {
        try (
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
    
        ) {
            String inputLine;
            while((inputLine = in.readLine()) != null) {
                chatServer.broadcastMessage(inputLine);
            }
    
            try {
                in.close();
            } catch (IOException e) {
                System.err.println("Couldn't close input stream");
            }
        } catch(IOException e) {
            System.err.println("Got an IOException in ClientHandler");
        }
    }
    
    此方法仅等待来自其处理的客户端的输入,然后使用以下方法将输入发送到服务器:

  • 广播消息(字符串消息):


    关闭这些流将导致下次尝试使用它们时出现IOException。请注意,
    Socket.getInputStream()
    将为您获取一个相同的流实例,而不是新创建的流实例


    确保只有在完成通信时,才关闭InputStream、OutputStream和套接字本身。

    当您尝试迭代连接的客户端时,什么可以防止它们被修改?关闭这些流将导致下次尝试使用它们时出现IOException。请注意,
    Socket.getInputStream()
    将为您获取流的相同实例,而不是新创建的实例。@DavidSchwartz嗯,我想什么都没有。但我想这更像是一个一致性问题,而不是什么导致了我的问题?但是,是的,这也需要解决。@Fildor好的,很高兴知道。虽然从这些方法中删除close()-行时,我仍然会遇到相同的错误。@JonatanStenbacka
    PrintWriter
    BufferedReader
    是自动关闭的,请参见“谢谢!”!我不知道
    Socket.getInputStream()
    只给我一个流的实例。删除我的close语句以及不使用“try with resources”-语句,从而防止流过早关闭,这样做是成功的。
    public void broadcastMessage (String message) {
    
        Iterator<Socket> iterator = this.connectedClients.iterator();
    
        while (iterator.hasNext()) {
            Socket currentSocket = iterator.next();
            try (                   
                PrintWriter out = 
                    new PrintWriter(currentSocket.getOutputStream(), true);
            ) {
                out.println("Server: " + message);
    
                out.close();
    
            } catch(IOException e) {
                System.err.println("Got an IOException error while reading or writing from/to client");
            }
        }
    }
    
    java.net.SocketException: socket closed
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(Unknown Source)
        at java.net.SocketInputStream.read(Unknown Source)
        at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
        at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
        at sun.nio.cs.StreamDecoder.read(Unknown Source)
        at java.io.InputStreamReader.read(Unknown Source)
        at java.io.BufferedReader.fill(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at java.io.BufferedReader.readLine(Unknown Source)
        at chat.ClientHandler.run(ChatServer.java:120)
        at java.lang.Thread.run(Unknown Source)