我在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);
}
}
}
}
答案 0 :(得分:3)
当您使用try-with-resources时,在try
部分初始化的对象将在try
块的末尾关闭。
因此,就像您的代码一样,对给定OutputStream
的{{1}}的任何后续调用都将失败,因为在第一次调用Socket
之后已经关闭了它。