-5

我有一个从 TCP 源读取数据的 Java 程序,一切正常,除非我的程序(充当数据源的客户端)速度更快,然后源可以响应 BufferedReader.ready() 抛出一个关闭我的异常TCP 连接,因为它应该。是否有任何首选方式/方法可以让 BufferedReader 等待新输入,因为我的源有时可能会有轻微延迟。

这是我正在谈论的部分:

 public aDataServer(String host, int port, StreamConnection aConnection) throws UnknownHostException, IOException {
            this.aConnection = aConnection;
            ndataServerSocket = new Socket(Inet4Address.getByName(host),port);
            ndataServerReader = new BufferedReader(new InputStreamReader(ndataServerSocket.getInputStream()));
        }


 public void run() {
            try {
                RemoteDevice dev = RemoteDevice.getRemoteDevice(aConnection);
                OutputStream outputStream = aConnection.openOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(outputStream);
                do {
                    try {
                        String ndata = ndataServerReader.readLine();


                          osw.write(ndata+"\n");
                          osw.flush();
                          LOG.log(Level.INFO,"Sent");


                    } catch(IOException io) {
                        LOG.log(Level.SEVERE, "Client device({0}) disconnected: \n{1}", new Object[]{dev.getFriendlyName(true), io.getMessage()});
                        break;
                    } 
                }while(ndataServerReader.ready());
            } catch (IOException ioe) {
                LOG.severe(ioe.getMessage());
            } finally {
                try {
                    if (ndataServerSocket != null) {
                                ndataServerSocket.close();
                    }
                     if (ndataServerReader
                             != null) {
                                ndataServerReader.close();
                    }
                } catch (IOException ex) {
                    LOG.log(Level.SEVERE, ex.getMessage());
                }
            }
4

1 回答 1

0

你不应该使用ndataServerReader.ready(). 您的 do/while 循环(几乎可以肯定只是一个 while 循环)似乎假设ndataServerReader.ready()表明有更多数据要读取,这不是它的用途。

Reader的Javadoc将该ready()方法描述为:

告诉这个流是否准备好被读取。

返回:如果保证下一个 read() 不会阻塞输入,则返回 true,否则返回 false。请注意,返回 false 并不能保证下一次读取将阻塞。

更糟糕的是,Reader.ready()如果读者在尝试读取数据之前会等待更多数据,则返回 false。这并不意味着Reader 已经完成,实际上您应该期望此方法在处理网络流时经常返回 false,因为它很容易出现延迟。

您的代码当前可能正在读取一行(在do块中)然后检查阅读器是否准备好(在 中while),它可能不是,然后成功退出。没有异常被抛出——如果是,你会看到一个SEVERE级别的日志消息。

而不是 using ,而是利用它返回ready()的记录行为:readLine()

包含行内容的字符串,不包括任何行终止字符,如果已到达流的末尾,则为 null

换句话说,只需执行以下操作:

String ndata = reader.readLine();
while (ndata != null) {
    osw.write(ndata+"\n");
    osw.flush();
    LOG.log(Level.INFO,"Sent");

    ndata reader.readLine();
}

足以读取整个输入流。

参考阅读:(reader.ready()) 和使用 for 循环读取文件有什么区别?

于 2013-03-10T20:37:12.110 回答