Има ли начин да прочетете входния поток за определен период от време?

Имам ситуация, при която нишка отваря telnet връзка към целеви m/c и чете данните от програма, която изплюва всички данни в своя буфер. След като всички данни бъдат изчистени, целевата програма отпечатва маркер. Темата ми продължава да търси този маркер, за да затвори връзката (успешно четене).

Понякога целевата програма не отпечатва никакъв маркер, тя продължава да изхвърля данните и моята нишка продължава да ги чете (нито един маркер не се отпечатва от целевата програма).

Така че искам да прочета данните само за определен период от време (да речем 15 минути/конфигурируем). Има ли някакъв начин да направите това на ниво API на Java?


person BoCode    schedule 03.03.2011    source източник
comment
Надявам се, че разбрах правилно въпроса ви, но когато четете данни с помощта на InputStream, извикващ read() с буфер от да кажем 1024 байта, можете да преброите времето, което сте прекарали в четене, като вземете разликата до началния час, за всеки цикъл, изразходван от вашия метод четене.   -  person joecks    schedule 03.03.2011
comment
Да, този подход работи, но не е ли това неоптимално?   -  person BoCode    schedule 03.03.2011


Отговори (4)


Използвайте друга нишка, за да затворите връзката след 15 минути. Като алтернатива можете да проверявате след всяко четене дали са изминали 15 минути и след това просто да спрете четенето и да почистите връзката, но това ще работи само ако сте сигурни, че отдалеченият сървър ще продължи да изпраща данни (ако не, четенето ще блокира за неопределено време).

person Community    schedule 03.03.2011
comment
java има вграден механизъм за изчакване на сокет, няма нужда да създавате нишка за това. - person krtek; 03.03.2011
comment
setSoTimeout задава времето за изчакване на всяко повикване на read. Ако отдалеченият край постоянно извежда данни, това няма да помогне. Вижте download.oracle. com/javase/1.4.2/docs/api/java/net/ - person ; 03.03.2011
comment
Времето за изчакване ще работи само ако нишката е блокирана при операция за четене. Няма да работи, ако нишката чете безкрайно данни, идващи от сървъра (което изглежда е случаят с OP) - person JB Nizet; 03.03.2011

Като цяло не. Входящите потоци не предоставят функционалност за изчакване.

Но във вашия конкретен случай, тоест четене на данни от сокет, да. Това, което трябва да направите, е set SO_TIMEOUT на вашия сокет до ненулева стойност (времето за изчакване, от което се нуждаете в милисекунди). Всички операции за четене, които блокират за определеното време, ще изхвърлят SocketTimeoutException.

Внимавайте обаче, тъй като въпреки че връзката ви със сокет е все още валидна след това, продължаването на четенето от нея може да доведе до неочакван резултат, тъй като вече сте изхабили наполовина данните си. Най-лесният начин да се справите с това е да затворите връзката, но ако следите колко вече сте прочели, можете да изберете да възстановите и да продължите да четете.

person biziclop    schedule 03.03.2011

Ако използвате Java Socket за вашата комуникация, трябва да погледнете setSoTimeout(int) метод.

Операцията read() на сокета ще блокира само за определеното време. След това, ако не бъде получена информация, ще бъде повдигнато java.net.SocketTimeoutException и ако се третира правилно, изпълнението ще продължи.

person krtek    schedule 03.03.2011

Ако сървърът наистина изхвърля данни завинаги, клиентът никога няма да бъде блокиран при операция за четене. Така можете редовно да проверявате (между четенията) дали текущото време минус началното време е надвишило вашето конфигурируемо забавяне и да спрете четенето, ако е така.

Ако клиентът може да бъде блокиран при синхронно четене, чакайки сървърът да изведе нещо, тогава можете да използвате SocketChannel и стартирайте нишка на таймер, която прекъсва основната нишка за четене или изключва нейния вход, или затваря канала.

person JB Nizet    schedule 03.03.2011