简体   繁体   English

Java while(true)循环运行一次

[英]Java while(true) loop runs once

I am writing a Server-Multiclient communication application, and I need to make a Thread that loops and accepts clients. 我正在编写一个服务器-多客户端通信应用程序,并且需要创建一个循环并接受客户端的Thread My current code is: 我当前的代码是:

Thread acceptor = new Thread() {
    public void run() {
        while(true){
            System.out.println("looking for clients");
            try{
                Socket s = serverSocket.accept();
                    clientList.add(new ConnectionToClient(s));
                }
                catch(IOException e){ e.printStackTrace(); }
            }
        }
    }
};
acceptor.setDaemon(true);
acceptor.start();

However, when I run my application, the text looking for clients only appears one time, and no clients can connect. 但是,当我运行应用程序时, looking for clients的文本只会出现一次,并且没有客户端可以连接。

I don't understand why my while(true) loop isn't actually looping, and only running once. 我不明白为什么我的while(true)循环实际上没有循环,只运行了一次。

EDIT: 编辑:

The ConnectionToClient constructor is: ConnectionToClient构造函数为:

ConnectionToClient(Socket socket) throws IOException {
    this.socket = socket;
    in = new ObjectInputStream(socket.getInputStream());
    out = new ObjectOutputStream(socket.getOutputStream());

    Thread read = new Thread(){
        public void run(){
            while(true){
                try {
                    Object obj = in.readObject();
                    messages.put(obj);
                } catch(IOException | ClassNotFoundException | InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    read.start();
 }

You're calling acceptor.setDaemon(true); 您正在调用acceptor.setDaemon(true); .

Its Javadoc explains: 其Javadoc说明:

Marks this thread as either a daemon thread or a user thread. 将此线程标记为守护程序线程或用户线程。 The Java Virtual Machine exits when the only threads running are all daemon threads. 当仅运行的所有线程都是守护程序线程时,Java虚拟机将退出。

So you're marking your only running thread as a daemon thread (since your main thread ends when the main method ends). 因此,您将唯一正在运行的线程标记为守护程序线程(因为主线程在main方法结束时结束)。 You're lucky that you got one iteration of the loop, since your VM almost immediately exits as there are no more non-daemon threads. 您很幸运,得到了循环的一次迭代,因为没有更多的非守护线程,您的VM几乎立即退出了。

Solution: remove the line that reads acceptor.setDaemon(true); 解决方案:删除读取acceptor.setDaemon(true);


Your updated post shows the other problem, the constructor ConnectionToClient(Socket socket) inadvertently tries to read from the Socket , which blocks the acceptor thread until the client sends data. 您更新后的帖子显示了另一个问题,构造函数ConnectionToClient(Socket socket)意外地尝试从Socket读取,它会阻塞接收器线程,直到客户端发送数据为止。

The problem is the constructor of ObjectInputStream tries to read the header of the object stream. 问题是ObjectInputStream的构造方法试图读取对象流的标头。

Therefor, you should move the construction of the ObjectInputStream and ObjectOutputStream into the read Thread, so that this doesn't block the acceptor Thread. 因此,您应该将ObjectInputStreamObjectOutputStream的构造移到read Thread中,以免阻塞acceptor Thread。

Ok, thanks to @ErwinBolwidt. 好的,感谢@ErwinBolwidt。

The problems were: 问题是:

1) The .setDaemon(true) was causing problems. 1) .setDaemon(true)引起了问题。

2) Creating the ObjectInputStream before the client was connected was reading the header that needed to be sent to the server, and blocking the client from sending it to the server. 2)在连接客户端之前创建ObjectInputStream的过程是读取需要发送到服务器的标头,并阻止客户端将其发送到服务器。 Moving that to the read thread allowed the client to actually connect to the server. 将其移至读取线程可以使客户端实际连接到服务器。

Thanks again @ErwinBolwidt. 再次感谢@ErwinBolwidt。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM