Java BufferedReader, как только позвонить, если не заблокирует? - PullRequest
0 голосов
/ 26 марта 2012

У меня есть 2 сокета, и я использую BufferedReader вокруг его InputStreams. То, что я пытаюсь сделать, это взять весь ввод из первого сокета и отправить его в другой сокет (и наоборот).

Проблема в том, что если первый не отправит сообщение, он все равно заблокирует первый 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 не готов дать мне некоторые данные? Я видел метод ready () в BufferedReader и пытался использовать in0.ready() && readLine(), но это вызывает бесконечный цикл, поскольку ни один из буферизованных считывателей, кажется, никогда не был «готов». Кроме того, я уверен, что сообщения, отправляемые через конец сокета в символах новой строки, поэтому readLine () должен обрабатываться правильно!

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 26 марта 2012

Попробуйте использовать setSoTimeout , чтобы установить тайм-аут для вашего read (), тогда вам просто нужно перехватить исключение SocketTimeoutException, если таймер истек.

0 голосов
/ 26 марта 2012

Самый простой подход - использовать два потока.Таким образом, вам не нужно писать собственный код планирования, чтобы определить, какой поток должен быть запущен.КСТАТИ: Код для копирования из одного сокета в другой одинаков в каждом потоке, что уменьшает дублирование.

Для управления вашими потоками я бы использовал ExecutorService, который облегчит отключение потоков.

0 голосов
/ 26 марта 2012

Здесь перерыв и продолжение ключевые слова - ваши друзья.

...