【问题标题】:while loop only stops at first loop then continues to run indefinitelywhile 循环仅在第一个循环处停止,然后无限期地继续运行
【发布时间】:2016-09-16 04:20:11
【问题描述】:

此练习程序的目标只是让客户端连续发送用户通过键入和按回车键输入的消息字符串并将其打印到控制台。第一次,Server.java 中的String messageFromClient = in.readLine(); 似乎阻塞(调试器不会让我退出)。然而,在向它发送“hello”之类的消息后,它会继续运行而不再阻塞。

我已经搜索了几个小时,但我想我只是没有在寻找解决方案的正确位置。

此链接Java InputStream blocking read 可能是我发现的最接近的可能对我有帮助的东西。

客户端.java

import java.io.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.*;
import java.net.InetAddress;
import java.util.Scanner;

public class Client {
    static Socket connectionToServer;
    public static void main(String[] args) {
        try{
            connectionToServer = new Socket("192.168.1.66", 6969);
            InetAddress inetAddress = connectionToServer.getInetAddress();
            System.out.print(
                    "Connection successful" +
                    "Connected to " + inetAddress.getHostAddress() +
                    "at " + inetAddress.getHostName() + "\n"
            );

            while(true) {
                String input = System.console().readLine();
                OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream());
                dOut.write(input, 0, input.length());
                //dOut.flush();
                dOut.close();
            }

        } catch (IOException exception){
            System.out.print("Failed to create socket");
        }

    }
}

服务器.java

import java.io.*;
import java.net.*;

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket;
        try {
            serverSocket = new ServerSocket(6969);
            System.out.print("Server is up and running \n");
        } catch (IOException exception){
            serverSocket = null;
            System.out.print("Cannot create ServerSocket");
        }

        while (true){
            try {
                System.out.print("Waiting from client.");
                Socket socket = serverSocket.accept();
                Thread newClientSocket = new Thread(new ServerThread(socket));
                newClientSocket.start();
                System.out.print("New thread created");
            } catch (IOException exception){
                System.out.print("Failed to create socket");
            }
        }
    }
}
////////////////////////////////////////////////////////////
class ServerThread implements Runnable{
    private Socket socket;
    //constructor
    ServerThread(Socket socket){
        System.out.print("I am a new thread");
        this.socket = socket;
    }

    public void run(){
        while(true){
            try{
                System.out.print("Waiting for input.");
                InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
                BufferedReader in = new BufferedReader(inputStreamReader);
                String messageFromClient = in.readLine();
                System.out.print(messageFromClient);
            } catch (IOException exception) {
                System.out.print(exception);
                break;
            }
        }
    }
}

【问题讨论】:

    标签: java serversocket


    【解决方案1】:

    您不应该为每个循环迭代构造一个新的BufferedReader,因为 BufferedReader 将尝试完全填充其缓冲区并可能读取超出第一行末尾的内容 - 并且该数据将丢失,因为您正在在仅读取第一行之后构造一个 new BufferedReader

    将 BufferedReader 的构造移出循环,这应该会对您有所帮助。另外,请确保在完成后关闭套接字。

    public void run() {
        try {
            try {
                InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
                BufferedReader in = new BufferedReader(inputStreamReader);
                while (true) {
                    System.out.print("Waiting for input.");
                    String messageFromClient = in.readLine();
                    System.out.print(messageFromClient);
                }
            } finally {
                socket.close();
            }
        } catch (IOException exception) {
            System.out.print(exception);
            // TODO: handle exception
        }
    }
    

    在发送端,你不应该为每一行关闭套接字的 OutputStream,因为一旦你关闭它,你就不能再使用它了。您应该在字符串之后向服务器发送一个换行符,因为Console.readLine() 方法不会将它包含在其返回值中。

            OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream());
            while(true) {
                String input = System.console().readLine() + "\n";
                dOut.write(input, 0, input.length());
            }
            dOut.close();
    

    【讨论】:

      【解决方案2】:

      Console.readLine() 不包含终止字符。 BufferedReader.readLine() 阻塞,直到它得到一个终止换行符

      改变这个:

      String input = System.console().readLine();
      

      到这里:

      String input = System.console().readLine() + System.lineSeparator();
      

      【讨论】:

        猜你喜欢
        • 2011-10-16
        • 2015-07-26
        • 1970-01-01
        • 2019-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        相关资源
        最近更新 更多