【问题标题】:Java BufferedReader, how to only call if will not block?Java BufferedReader,如果不会阻塞,如何只调用?
【发布时间】:2012-04-09 16:39:41
【问题描述】:

我有 2 个套接字,我在它的 InputStreams 周围使用 BufferedReader。我要做的是从第一个套接字获取所有输入并将其发送到另一个套接字(反之亦然)。

问题是如果第一个没有发送消息,即使第二个套接字已经发送了一些数据并且准备好了,它仍然会在第一个 readLine() 上阻塞。我想继续这种不使用额外线程的简单方法。

这是我编写的一些代码,如您所见,我有 2 个 BufferedReader(in0 和 in1),程序卡在 in0.readLine()(阻塞)。

private void network()
{
    PrintWriter out0 = null, out1 = null;
    BufferedReader in0 = null,in1 = null;
    try{
            //clients[] is an array of Socket[2]
        in0 = new BufferedReader(new InputStreamReader(clients[0].getInputStream()));
        out0 = new PrintWriter(clients[0].getOutputStream(), true);
        in1 = new BufferedReader(new InputStreamReader(clients[1].getInputStream()));
        out1 = new PrintWriter(clients[1].getOutputStream(), true);
      } catch (IOException e) {
        System.out.println("Accept failed: 4445");
        System.exit(-1);
      }

    int count = 1;
    while(true)
    {
        System.out.println("network check loop # " + count);
        ++count;
        String nextMessage = null;
        try {
            if( (nextMessage = in0.readLine()) != null)
            {
                this.relayMessage(nextMessage,out1);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println("Middle of network check loop");
        nextMessage = null;

        try {
            if((nextMessage = in1.readLine()) != null)
            {
                this.relayMessage(nextMessage,out0);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

如果 in0 还没有准备好给我一些数据,我怎么能跳过那个语句?我已经看到 BufferedReader 的 ready() 方法并尝试使用 in0.ready() && readLine() 但这会导致无限循环,因为这两个 bufferedreader 似乎都没有“准备好”。同样,我确信通过套接字发送的消息以换行符结束,因此 readLine() 应该正确处理!

有什么想法吗?

【问题讨论】:

    标签: java sockets inputstream bufferedreader


    【解决方案1】:

    尝试使用setSoTimeout 为您的 read() 设置一个超时,然后如果计时器已过期,您只需捕获 SocketTimeoutException。

    【讨论】:

    • 这听起来不错,我会试试的
    • 还看看什么是“非阻塞套接字”,它与 setSoTimeout 相关,可能是您正在寻找的。 (你会在 google 上找到很多例子)
    【解决方案2】:

    这里 breakcontinue 关键字是您的朋友。

    【讨论】:

      【解决方案3】:

      最简单的方法是使用两个线程。这样您就不必编写自己的调度代码来确定应该运行哪个线程。顺便说一句:从一个套接字复制到另一个套接字的代码在每个线程中都是相同的,从而减少了重复。

      为了管理你的线程,我会使用一个 ExecutorService,这将使关闭线程更容易。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-24
        • 2013-11-16
        • 2013-10-23
        • 2018-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多