Java while(true) 循环在线程内只执行一次

标签 java multithreading

我正在尝试用 Java 实现一个简单的客户端-服务器应用程序。

代码如下:

客户端.java

public class Client implements Runnable {
    private String hostName;
    private int portNumber;
    private String message;

    private Socket socket;
    private PrintWriter writer;
    private BufferedReader reader;

    public Client(String hostName, int portNumber, String message) {
        this.hostName = hostName;
        this.portNumber = portNumber;
        this.message = message;
    }

    public void connect() {
        try {
            socket = new Socket(hostName, portNumber);
            writer = new PrintWriter(socket.getOutputStream(), true);
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            writer.println(message);
        } catch (UnknownHostException e) {
            System.err.println("Could not resolve the host name '" + hostName + "'.");
        } catch (IOException e) {
            System.err.println("Could not get the I/O for the connection to '" + hostName + "'.");
        }
    }

    private void listenForMessages() {
        while (true) {
            try {
                System.out.println("In loop!");
                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                System.err.println(e.getMessage());
            }
        }
    }

    public void run() {
        connect();
        listenForMessages();
    }
}

服务器.java

public class Server implements Runnable {
    private int portNumber;
    private String message;

    private ServerSocket serverSocket;
    private Socket clientSocket;
    private PrintWriter writer;
    private BufferedReader reader;

    public Server(int portNumber, String message) {
        this.portNumber = portNumber;
        this.message = message;
    }

    private void listen() {
        try {
            serverSocket = new ServerSocket(portNumber);
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

        while (true) {
            try {
                clientSocket = serverSocket.accept();
                writer = new PrintWriter(clientSocket.getOutputStream(), true);
                reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                String line;
                while ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }

                writer.println(message);
            } catch (IOException e) {
                System.err.println(e.getMessage());
                break;
            }
        }
    }

    public void run() {
        listen();
    }
}

这是主类:

public class Test {
    public static void main(String[] args) {
        Client client = new Client("localhost", 4444, "Hello from client!");
        Server server = new Server(4444, "Hello from server!");

        Thread serverThread = new Thread(server);
        serverThread.start();

        Thread clientThread = new Thread(client);
        clientThread.start();
    }
}

代码的逻辑很简单:客户端和服务器都在 while(true) 循环中等待消息。

服务器listen 方法中的while 循环执行得很好。但是,在 listenForMessages 方法内部,循环似乎只执行一次。我只在屏幕上看到一个“In loop”。

你能找出问题所在吗?

提前致谢!

最佳答案

However, inside the listenForMessages method, the loop seems to be executed only once. I only see one "In loop" printed on the screen.

其实不是因为循环只执行一次,而是因为 reader.readLine() 会让当前线程等待,直到它接收到一整行,这里如果你检查代码Server,它首先读取并无限循环读取,因为 reader.readLine() 只会在流的末尾返回 null所以在这种情况下套接字何时关闭。

如果你想在客户端和服务器之间实现某种乒乓球,只需在一侧读取然后写入,然后在另一侧写入和读取,如下所示:

客户端代码:

public void connect() {
    try {
        socket = new Socket(hostName, portNumber);
        writer = new PrintWriter(socket.getOutputStream(), true);
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

    } catch (UnknownHostException e) {
        System.err.println("Could not resolve the host name '" + hostName + "'.");
    } catch (IOException e) {
        System.err.println(
            "Could not get the I/O for the connection to '" + hostName + "'."
        );
    }
}

private void listenForMessages() {
    while (true) {
        try {
            System.out.println("In loop!");
            // Write the message for the server
            writer.println(message);
            // Read the message from the server
            System.out.println(reader.readLine());
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }
    }
}

服务器代码:

while (true) {
    try {
        clientSocket = serverSocket.accept();
        writer = new PrintWriter(clientSocket.getOutputStream(), true);
        reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        while (true) {
            // Read the message from the client
            System.out.println(reader.readLine());
            // Write the message for the client
            writer.println(message);
        }


    } catch (IOException e) {
        System.err.println(e.getMessage());
        break;
    }
}

输出:

In loop!
Hello from client!
Hello from server!
In loop!
Hello from client!
Hello from server!
...

关于Java while(true) 循环在线程内只执行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40396692/

相关文章:

java - 如何从 HTTP post 请求中删除 Accept-char header

java - AtomicReference.compareAndSet() 使用什么来确定?

java - 如何制作曲线形状的 JSlider?

c# - 等待自定义函数

ios - GCD 没有获取网络内容来获取部署在 Internet 上的字符串

java - 如何强制 Eclipse 将 java 项目视为 java 项目?

java - 从批处理文件向 Java 进程提供输入

java - 将应用程序链接到 Swing GUI 的最佳方式是什么?

multithreading - 如何强制主线程等待其所有子线程在 Haskell 中完成

c# - 如何获取所有正在运行的线程的列表