Java广播消息到arraylist

Java广播消息到arraylist,java,Java,我在Java中的一个练习中遇到了一个问题,下面是我的代码。 问题在于broadcastMessage方法,在ClientHandler类中执行它之后,它并没有返回到这个类(它关闭了连接) 提前谢谢 克莱恩汉德勒 import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import

我在Java中的一个练习中遇到了一个问题,下面是我的代码。 问题在于broadcastMessage方法,在ClientHandler类中执行它之后,它并没有返回到这个类(它关闭了连接)

提前谢谢

克莱恩汉德勒

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.StringTokenizer;

public class ClientHandler implements Runnable {
    private Socket s;
    private static int loginCount=0;

    public ClientHandler(Socket s) {
        this.s=s;
        loginCount++;
    }

    @Override
    public void run() {
        try(InputStream is=s.getInputStream();
                OutputStream os=s.getOutputStream();
                Scanner sc=new Scanner(is);
                PrintWriter pw=new PrintWriter(os,true)){
            pw.println("Polaczyles sie z serwerem echo.");
            pw.flush();
            boolean end=false;
            while(!end && sc.hasNextLine()) {
                String line=sc.nextLine();
                StringTokenizer st=new StringTokenizer(line);
                String firstToken=st.nextToken();
                switch(firstToken) {
                case "q":{
                    CalculatorMain.unregisterSocket(s);
                    end=true;
                    break;
                }
                case "count":{
                    pw.println("Aktualnie zalogowano "+loginCount +" uzytkowników");
                    break;
                }
                case "end":{
                    pw.println("Go to CalculatorMain");
                    CalculatorMain.broadcasMessage("Serwer zostanie zamkniety");
                    pw.println("Returned from CalculatorMain");
                    //Thread.currentThread().sleep(5000);
                    //System.exit(0);
                }
                case "sum":{
                    String secondToken,thirdToken;
                    secondToken=st.nextToken();
                    thirdToken=st.nextToken();
                    int sum=Integer.parseInt(secondToken)+Integer.parseInt(thirdToken);
                    pw.println("suma="+sum);
                    break;
                }
                default:{
                    pw.println("Niepoporawne polecenie.");
                }
                }
            }
            loginCount--;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
计算器

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class CalculatorMain {
    private static ArrayList<Socket> gniazda;

    public static void main(String[] args) throws IOException {
        try(ServerSocket ss=new ServerSocket(8189)){
            gniazda=new ArrayList<>();
            while(true) {
                Socket s=ss.accept();
                Thread t=new Thread(new ClientHandler(s));
                registerSocket(s);
                t.start();
            }
        }
    }

    public static void registerSocket(Socket s) {
        gniazda.add(s);
    }

    public static boolean unregisterSocket(Socket s) {
        return gniazda.remove(s);
    }

    public static void broadcasMessage(String msg) throws IOException {
        for(Socket s: gniazda) {
            try(OutputStream os=s.getOutputStream();
                    PrintWriter pw=new PrintWriter(os,true)){
                pw.println(msg);
            }
        }
    }
}
import java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.io.PrintWriter;
导入java.net.ServerSocket;
导入java.net.Socket;
导入java.util.ArrayList;
公共类计算器{
私有静态阵列列表gniazda;
公共静态void main(字符串[]args)引发IOException{
try(ServerSocket ss=newserversocket(8189)){
gniazda=newarraylist();
while(true){
套接字s=ss.accept();
螺纹t=新螺纹(新夹具);
登记簿簿;
t、 start();
}
}
}
公共静态无效寄存器套接字(套接字s){
加上;
}
公共静态布尔取消注册套接字(套接字s){
返回gniazda。移除;
}
公共静态void broadcasMessage(字符串msg)引发IOException{
用于(插座s:gniazda){
try(OutputStream os=s.getOutputStream();
PrintWriter pw=新的PrintWriter(操作系统,真)){
pw.println(msg);
}
}
}
}

使用try with resources时,在
try
部分初始化的对象将在
try
块末尾关闭


因此,正如您的代码一样,对给定的
套接字的
OutputStream
的任何后续调用都将失败,因为在第一次调用
broadcasMessage

后,它已经关闭。感谢Arnaud的快速响应,您知道如何更改它吗?您可以使用常规的
尝试
,并将outputstream和printwriter放入块中。然后,要在完成后关闭,可以关闭
unregisterSocket
方法中的套接字。再次感谢。解决了的