если я установлю тайм-аут для сокета, будет ли его входной поток по-прежнему вызывать исключение тайм-аута, даже если я оберну его другим типом

Я хочу попытаться прочитать входной поток сокета в течение определенного времени, а затем сделать что-то еще, если я не получу никаких входных данных, я знаю, что могу установить тайм-аут для сокета, который сделает это

mySocket.setSoTimeout(200);

но будет ли он по-прежнему работать (будет ли InputStream по-прежнему вызывать исключение для моего блока catch), даже если я инкапсулирую его в ObjectInputStream

public void startClient(){
    try {
        connection = new Socket(InetAddress.getByName(hostName), port);
        output = new ObjectOutputStream( connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream( connection.getInputStream());
    }
    catch (IOException ex) {
        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
    }
    ExecutorService worker = Executors.newSingleThreadExecutor();
    worker.execute( this );
}

и есть ли другой способ сделать это, если это не работает. плюс, если поток начнет чтение и истечет время ожидания, он остановится в середине или будет продолжаться до тех пор, пока в потоке не останется байтов, как в: будет ли тайм-аут потока после того, как он начнет читать объект, если пройдет 200 мс?

я хочу сделать что-то вроде этого

    while(!connection.isClosed()){
        try{
            com = (String) input.readObject();
            if(com.equals("TERMINATE CONNECTION")){
                closeConnection();
            }else if(com.equals("SEND DATA")){
                sendData();
            }
        }catch(timeout exception){
             if( timedout and want to do something){ do something else ....}
        }
            com="";
  }

Спасибо всем


person Nicolas Hanout    schedule 12.07.2015    source источник


Ответы (1)


Если я установлю тайм-аут для входного потока сокета

Вы не «устанавливаете тайм-аут для входного потока сокета». Вы устанавливаете время ожидания на самом сокете.

будет ли он работать, даже если я приведу этот поток к другому типу?

Здесь нет приведения к другому типу. Вы оборачиваете входной поток сокета в другой тип. Это никак не может повлиять на тайм-аут чтения сокета, и сокет даже не узнает, что вы это сделали.

Короче вопрос не имеет смысла.

плюс, если поток начнет читать и истечет время ожидания, он остановится в середине или будет продолжаться до тех пор, пока в потоке не останется байтов

Я тоже не могу разобраться в этом, но если вы получаете тайм-аут, это означает, что данные не поступили в течение периодов тайм-аута. Это не разрывает связь. Однако это может сломать ObjectInputStream,, если вы каким-то образом получите тайм-аут в середине чтения объекта.

NB:

  1. Тайм-аут проявляется как SocketTimeoutException,, а не как то, что вы обнаруживаете в цепочке if-else.

  2. Неправильно зацикливаться, пока connection.isClosed() возвращает false. Это не становится правдой волшебным образом, когда одноранговый узел закрывает соединение. В этом случае правильная техника состоит в том, чтобы зацикливаться до тех пор, пока вы не получите EOFException.

person user207421    schedule 12.07.2015
comment
спасибо, это было очень полезно. и да, извините, я не хотел писать состав, я не обращал внимания, пытаясь понять, как написать свой первый пост. и я использую connection.isClosed(), поэтому он прерывает цикл, если я вызываю connection.close() из этого приложения, и я обрабатываю EOFException в блоке catch, чтобы обработать какой-то другой код перед завершением цикла - person Nicolas Hanout; 12.07.2015
comment
да, это то, что я имел в виду по поводу тайм-аута при чтении объекта, есть ли способ узнать, прервал ли поток поток для повторной отправки объекта? это вызовет исключение? - person Nicolas Hanout; 12.07.2015
comment
Это вызовет исключение. Закрытие потока из другого потока проблематично и может работать не на всех платформах. Лучший метод - отключить сокет для ввода. Это вызовет EOFException. - person user207421; 12.07.2015