Java广播消息到arraylist

时间:2019-02-08 10:52:25

标签: java

我在Java中进行一次练习时遇到了问题,下面我提供了代码。 问题在于广播消息方法,在ClientHandler类中执行该方法后,它没有返回到该类(其关闭连接)。

谢谢。

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();
        }
    }

}

CalculatorMain

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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

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

因此,就像您的代码一样,对给定OutputStream的{​​{1}}的任何后续调用都将失败,因为在第一次调用Socket之后已经关闭了它。