# Möglichkeit zum Timeout eines Process



## Einwegdose (11. Jul 2006)

Guten Tag !

Ich habe im Moment ein Problem mit unserem guten alten Freund dem BufferedReader  :autsch: 

Zum Situation:
Mit einem Process wird das Programm cURL (mit Parametern) aufgerufen, welches verschiedene GET/POST-Aufgaben erledigt. Über den Input und Error-Stream hole ich die Ausgabe (also Statusanzeige, ...) in mein Java-Programm.
Das klappt auch alles wunderbar über Threads. Das Problem besteht nun (wie bei Streams), wenn das Ende des InputStreams erreicht ist, daher das Programm keine Ausgabe mehr bringt. Der BufferedReader hängt sich dann bei readLine() auf, da kein \r bzw \n kommt ...

Leider weiss ich nun nicht wann diese letzte Zeile erreicht ist - deshalb wollte ich fragen ob es auch sowas wie ein Timeout bei einem Socket für einen Process gibt, oder jemand einen anderen Lösungsvorschlag hat (aber bitte keine ala 'Es gibt doch von Apache den HttpClient' oder sowas !) .. ansonsten weiss ich nicht, wie ich das Problem sicher lösen kann.

Danke schonmal  :toll:


----------



## Murray (11. Jul 2006)

Evtl. hilft Dir Process#waitFor weiter. Damit wird solange gewartet, bis der aufgerufene Prozess beendet wurde. Danach macht es wohl keinen Sinn mehr, auf Eingaben zu warten.


----------



## Einwegdose (11. Jul 2006)

Hmm ich glaube nicht dass das was hilft. Soweit ich weiss, hängt sich der Prog bei waitFor() solange auf, bis er fertig ist. Aber solange er nicht fertig ist, lese ich jede Sec den InputStream aus ... und das könnte ich ja dann nicht mehr machen ! Ich brauch ja die Ausgabe solange sie noch kommt


----------



## foobar (11. Jul 2006)

Das Problem kenne ich gut. Du darfst indem Fall keinen BufferedReader verwenden, weil der immer auf das CRLF wartet, was es in dem Fall nicht gibt. 
Ich habe es gelöst indem ich in ein Byte-Array lese und dann gucke wieviel Daten noch vorhanden sind und dann den Rest lese.
Guckst du hier: http://www.java-forum.org/de/viewtopic.php?t=34099&highlight=simplehttpclient


----------



## Einwegdose (12. Jul 2006)

Hi!

Deine Idee ist nicht schlecht, aber (soweit ich es probiert habe) für diesen Zweck leider sinnlos.
Der Grund: Das Programm (cURL) gibt in nicht genau festgelegten Zeiträumen den Status aus. Diese Status-Zeile brauche ich dann komplett (sobald sie verfügbar ist) um sie dann jewals weiterzuverarbeiten.
Eine Zeile ist immer 78 Chars lang. Wenn ich nun Bytes einlese, sind zu dem Zeitpunkt höchst unwahrscheinlich genau n * 78 Bytes verfügbar .. aber soviele brauche ich immer ! Ansonsten habe ich unfertige Statuszeilen mit denen ich nichts anfangen kann. 

Bei dem folgenden Beispiel versuche ich eine komplette Zeile einzulesen. Allerdings fehlen pro Durchlauf immer mehr Bytes, die dann auch nicht beim nächsten Durchlauf am Anfang stehen, sondern verloren sind ...


```
while ( true ) {
     byte arr[] = new byte[78];
     err.read(arr);
     for ( byte b : arr ) {
      System.out.print((char)b);
     }
     System.out.println("\r\n");
     Thread.sleep(1000);
     if ( "erstmalegal".equals("") ) break;
    }
```

Dagegen steht ganz klar der Vorteil des BufferedReaders, mir immer eine ganze Zeile (genau soviel wieviel ich  brauche) zurückzuliefern. Wenn die verarbeitet ist, hole ich die nächste, etc, etc. Eigentlich perfekt .. nur das sie am Ende hängenbleibt da kein CRLF kommt -.- .. Ich versuche da mal morgen noch was hinzubekommen , weiss allerdings bisher nicht wie :bahnhof: 

Falls noch andere Vorschläge da sind, ich bin ganz Ohr 

Gruss & gn8 ^^


Hmm mir ist gerade noch ne Idee gekommen, die allerdings depreciated wäre ..

Wenn ich den BufferedReader#readLine() befehl in einen extra Thread stecke, vorher noch die System#nanoTime abspeichere, und dann den Thread laufen lasse, könnte ich ihn ja dann zwangsweise abbrechen nach _n_ Nanosekunden wenn er sich nicht schon von alle beendet hat ( ==> eine Zeile ausgelesen werden konnte). Für den Zwangsabbruch müsste ich dann aber wohl eine der als depreciated markierten Methoden Thread#stop oder Thread#destroy anwenden.

Was haltet ihr davon ?


----------



## Murray (12. Jul 2006)

Einwegdose hat gesagt.:
			
		

> Hmm ich glaube nicht dass das was hilft. Soweit ich weiss, hängt sich der Prog bei waitFor() solange auf, bis er fertig ist. Aber solange er nicht fertig ist, lese ich jede Sec den InputStream aus ... und das könnte ich ja dann nicht mehr machen ! Ich brauch ja die Ausgabe solange sie noch kommt



Das ist schon klar; natürlich kommt man da nicht mehr mit einem Thread aus.

Also: Prozess starten, waitFor() in neuem Thread ausführen, Daten lesen, bis a) eine Zeile gelesen wurde oder b) der zweite Thread signalisiert, dass das Programm beendet worde ist.


----------



## Einwegdose (12. Jul 2006)

Ich habe es jetzt über einen weiteren Thread gelöst, der versucht immer neue readLines() auszulesen und diese dann in einem Vektor zu schreiben.
Von dem anderen Thread aus kann ich dann überprüfen, ob sich der Vektor vergrößert hat. Tut er dies innerhalb einer geraumen Zeit nicht mehr, wird davon ausgegangen dass der Prozess beendet ist.


----------



## Natorion (13. Jul 2006)

kannst du nit einfach beim programende von cURL manuell nen sysout mit CLRF machen? bzw irgendeinen speziellen string schicken damit dein programm erkennt, dass ende ist.


----------

