【问题标题】:When BufferedReader.read(char[]) returns -1?当 BufferedReader.read(char[]) 返回-1?
【发布时间】:2020-02-28 15:39:13
【问题描述】:

我正在使用 Evolis 卡片打印机 SDK,它使用 JsonRPC 通过 TCP 套接字与客户端通信。

我有一个制造商提供的 Java 示例,但是我在读取套接字时遇到了一些问题:

package MinimalClient;
import java.io.*;
import java.net.*;

public class MinimalClient 
{   
    public static void main(String[] args) 
    {
        try {
                String ip = "11.1.24.210";
                int port = 18000;
                char[] data = new char[1024];
                String request = "{\"jsonrpc\":\"2.0\",\"id\":\"1\",\"method\":\"CMD.SendCommand\",\"params\":{\"command\":\"Rfv\", \"device\":\"Evolis Primacy\", \"timeout\":\"5000\"}}"; 
                String answer = "";

                Socket socket = new Socket(ip,port);

                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                DataOutputStream out = new DataOutputStream(socket.getOutputStream());

                byte[] byteRequest = request.getBytes("UTF-8");

                out.write(byteRequest);

                out.flush();

                while( (br.read(data)) != -1 ) 
                {
                    answer = new String(data);
                    System.out.println(answer);
                }

                socket.close();
            } 
            catch (Exception e) 
            { 
                System.out.println("Communication failed :\n");
                System.out.println(" - check TCP communication is activated\n");
                System.out.println(" - check the service is activated\n");
                System.out.println(" - check your IP address and port\n");                          
            }
    }
}

我被困在while( (br.read(data)) != -1 ) 中,因为在第一个循环之后,BufferedReader.read 不会返回 -1 并一直停留在那里直到超时!

第一次运行得到回复内容的所有JSON,然后第二次运行卡住了,因为没有什么可读取的。

当 BufferedReader.read(char[]) 返回 -1 时?

【问题讨论】:

    标签: java sockets tcp sdk bufferedreader


    【解决方案1】:

    当缓冲区另一端的发送方完成发送数据流时,'read' 方法是否会返回 -1。通常从磁盘等持久存储中读取,当从磁盘中的文件中读取最后一个字符时,该方法返回-1。

    但是,这是一个“套接字”,而“发送者”位于网络的另一端。我怀疑“发送者”应该刷新()和关闭()他们的“输出流”一侧,以便您的“读取()”方法获得-1。

    您应该与您的供应商联系并检查一下。一切顺利,希望对您有所帮助。

    【讨论】:

    • 您的回答几乎是正确的。如果您有兴趣,请阅读我关于您的读者到达在其他地方打开以进行写入的文件末尾的条件的回答
    • 是的,这就是为什么我认为发送者仍然保持流打开并且从未关闭它,这使得这个 br.read() 认为发送者仍然会发送一些东西只是为了它的时间出去。您是否建议在“发送者”端有两个写入器到同一个“输出流”,第一个会“关闭”但第二个不会?有趣,但不确定两个人是否可以“写入”到同一个“输出流”。没试过。
    • 在这种情况下,发送方(服务器)不应关闭连接,因为这是打印机和客户端之间的连接,在关闭连接之前可能会有更多的交换。理论上我无法理解客户端 TCP 连接应该停止读取常见协议:HTTP(使用 keepalive),也许它使用开头声明的消息长度?
    【解决方案2】:

    BufferedReader.read(char[]) 如果 (a) 您已到达文件末尾并且 (b) 文件已打开以写入其他位置,则该文件将返回 -1。否则,它将等待更多数据写入流。

    解决这个问题的方法是检查整个JsonRPC消息是否已经发送,并关闭你这边的连接

                while( (br.read(data)) != -1 ) 
                {
                    answer = new String(data);
                    System.out.println(answer);
                    if (testForCompleteness(answer)) socket.close();
                }
    

    【讨论】:

    • 我的意思是,尽管使用这种方法,流阅读器也必须关闭。我的意思是 InputStreamReader 和 BufferedReader。我认为这是解决它的一种方法,但我们仍然不知道为什么在这种情况下发件人没有确认发送事实已完成。
    • 问题是关于流,而不是关于 json。
    • @Siva 关闭套接字后,InputStreamReader 和 BufferedReader 也会自动关闭。
    • @Silva 我不能 100% 肯定地告诉你为什么发件人没有关闭他们这边的套接字。但我认为他们很可能仍在收听来自您的新消息,他们会对此做出回应。您可能想尝试使用像 DataFetcher 这样的线程回调侦听器(tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/… 我几年前写的通过套接字进行通信)
    • 发送者让套接字保持打开状态,但关闭了我认为的输出流?
    猜你喜欢
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    相关资源
    最近更新 更多