【问题标题】:BufferedReader in Socket ProgrammingSocket 编程中的 BufferedReader
【发布时间】:2020-11-02 13:36:35
【问题描述】:

当我尝试从客户端发送输入时,如果我不在字符串末尾连接“\r\n”,我的输入流将永远等待。我看过各种类似的帖子,但找不到合适的解决方案。我的代码如下:

public void run() {
    
    PrintWriter out = null;
    BufferedReader in = null;
    try {
        out = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        String line;

        if (in.ready()) {
            if ((line = in.readLine()) != null) {
                System.out.println("Received from client: " + line);
                out.write("Echoing: " + line);
                out.flush();
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        out.close();
        try {
            in.close();
            clientSocket.close();
            System.out.println("Closing connection from " + socketAddress + ", #" + connectionId);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

【问题讨论】:

  • 一个因素当然是readLine() 返回没有尾随换行符的行(\r\n\n、NEL 字符)。 out.write("\r\n"); 还不错。
  • 我无法在客户端修改代码。我需要在服务器端采用不同的方法。
  • 客户端如何告诉服务器它已经发送了一个完整的消息?你能发布客户端的代码或它使用的通信协议的文档吗?
  • 客户端代码是PHP,我写了一个简单的脚本来测试。将与服务器通信的真实设备只能发送原始字节。 socket_write($socket, $message, strlen($message))
  • 服务器如何知道它是否收到了完整的$message,或者它是否必须等待来自客户端的更多数据?另外,当您在 cmets 中回复某人时,请使用 @ 标记用户,否则他们不会收到通知

标签: java sockets inputstream bufferedreader


【解决方案1】:

如果您只想读取已发送的部分数据,请使用read(char[]) 方法而不是readLine 方法。此方法将读取的字符数返回为int。示例:

     char[] buffer = new char[2000];
     int read;
     if ((read = in.read(buffer)) != -1) {
            String line = new String(buffer, 0, read);
            System.out.println("Received from client: " + line);
            out.write("Echoing: " + line);
            out.flush();
      }

接下来您将看到此代码有时无法读取您从 PHP 发送的整个消息,或者将两条或多条消息作为一条读取。

如果你想解决这个问题:

这永远行不通,也不是因为 PHP 或 Java。您正在使用 TCP,一种面向流的协议。无法保证您从 PHP 程序写入到套接字的消息会一并到达接收者。消息可能被分解,您需要多个套接字函数调用才能读取它。或者它可能会朝另一个方向发展,对read 的一次调用会返回多条消息。

解决方案是为消息添加某种框架,以便接收者知道何时收到完整的消息。如果消息本身是单行,则始终以换行符结束消息作为框架。另一种解决方案是放弃 TCP 并改用面向消息的协议(如 UDP),但这会带来其自身的复杂性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    相关资源
    最近更新 更多