我有一个简单的服务器客户端示例: FooServer.java
:
public class FooServer {
private Socket clientSocket;
public class ClientHandler implements Runnable {
private BufferedReader reader;
private PrintWriter writer;
public ClientHandler(Socket socket) {
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
String message;
System.out.println("start of server run()");
try {
writer = new PrintWriter(clientSocket.getOutputStream());
while ((message = reader.readLine()) != null) {
System.out.println("inside of server loop - get new message");
writer.println(message);
writer.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end of server run()");
}
}
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(5000);
while (true) {
clientSocket = serverSocket.accept();
Thread watchIncome = new Thread(new ClientHandler(clientSocket));
watchIncome.start();
System.out.println("got connection");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new FooServer().go();
}
}
以及 FooClient.java
:
public class FooClient {
private BufferedReader reader;
private PrintWriter writer;
private Socket socket;
public class ReadIncome implements Runnable {
@Override
public void run() {
System.out.println("start of client run()");
String mes;
try {
while ((mes = reader.readLine()) != null) {
System.out.println("inside of client loop");
System.out.println(mes);
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("end of client run()");
}
}
public void go(String writeOut) {
try {
socket = new Socket("127.0.0.1", 5000);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
//--------HERE-----------
//how long will this thread live?
Thread readerThread = new Thread(new ReadIncome());
readerThread.start();
writer.println(writeOut);
writer.flush();
}
public static void main(String[] args) {
FooClient foo = new FooClient();
foo.go("dummy text");
}
}
我运行fooserver.java,这反过来会产生新的 watchIncome
(从客户端查找消息的线程) while ((message = reader.readLine()) != null)
). 但在服务器中,它在 while(true)
无限循环,因此它不断产生新的线程来寻找传入的消息。
然而,在客户机中,并没有这样的无限循环。据我所知,在java中,线程运行 run()
方法和。。。完成了。线程已死机(即无法“重置”以再次运行)。而且,由于客户端不会产生新线程(与服务器中不同的是,没有无限循环),因此客户端不应该“等待”服务器的响应,因为线程应该已经死了(这就是我在java中理解线程的方式—只需运行 run()
方法一次)。
但相反,客户将挂在中间 run()
方法->只打印 inside of client loop
,永远不会结束。但既然线已经死了,那怎么可能呢?一次 readerThread.start();
,并且在方法内部 while ((mes = reader.readLine()) != null)
将计算为false(字符串没有任何内容,因此为null),并且方法完成后,不应等待服务器响应(因为我假设线程立即启动)。
此外,即使语句的计算结果为true(比如说,服务器是先启动的,所以客户机在启动时就得到响应),客户机也会再次挂断在客户机循环内部,在 run()
,但它不应该,因为没有循环,所以它应该继续到方法的末尾(从而到线程的末尾)。最后,我必须终止服务器进程(这是有意义的,因为我从未关闭服务器套接字),但是这样,客户机进程也将结束。但它应该已经死了。有人能解释一下,为什么客户“等待”,但它不应该?
暂无答案!
目前还没有任何答案,快来回答吧!