Java BufferedReader,如何只调用if会不会阻塞?

时间:2012-03-26 06:38:52

标签: java sockets inputstream bufferedreader

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

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

这是我编写的一些代码,因为你可以看到我有2个BufferedReaders(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(),但这会导致无限循环,因为两个缓冲的读取器似乎都没有“准备好”。同样,我确信通过套接字发送的消息以换行符结尾,因此readLine()应该正确处理!

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

此处中断继续关键字是您的朋友。

答案 1 :(得分:0)

尝试使用setSoTimeout在read()上设置超时,然后只需要在计时器到期时捕获SocketTimeoutException。

答案 2 :(得分:0)

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

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