Pipe Problem - "Pipe broken"
lima-city → Forum → Programmiersprachen → Java
broken
byte
code
datum
eintreffen
fehlermeldung
http
leser
netzwerk
problem
programm
programmteil
quere
run
schreiber
senden
starten
url
zeitversetzt laufen
zweite schreiber
-
Hallo.
Ich nutze in Java gerne Streams, um Daten zwischen verschiedenen Programmteilen auszutauschen. Ich kann dann Programme über das Netzwerk verbinden und wenn ich sie lokal verbinden möchte, einfach Pipes nutzen. (Pipe = PipedInputStream + PipedOutputStream)
Vor Kurzem bekam ich aber Fehlermeldungen und habe jetzt keinen Plan mehr, wie ich das Problem lösen könnte.
Zuerst mal Beispielcode, wo der Fehler auftritt:
http://paste42.de/7515/Pipe_Problem&linenr
Wenn jemandem etwas auffällt, das unsauber ist, nur her mit der Info. Ich korrigiere gerne, wenn mein Programm dann vielleicht lauffähig wird.
Zur Erklärung: Der eine Programmteil, der Leser liest die Bytes, die über die Pipe eintreffen und wertet sie aus.
Der andere Programmteil, der Schreiber sendet diese Bytes an den Leser. Vom Schreiber gibt es zwei Instanzen, d.h. beide sollen dem Leser Nachrichten schicken können. Damit sich die beiden nicht in die Quere kommen, gibt es den 'synchronized'-Block in Zeile 37.
Wenn diese zwei Schreiber aber zeitversetzt laufen, kommt es zur Fehlermeldung. Der erste Schreiber läuft los, sendet sein Byte und beendet sich. Dann sollte 10 sec. später der zweite Schreiber starten und sein Byte ebenfalls senden.
Allerdings dauert es keine 10 sec, sondern nach 2 bis 3 sec. kommt diese Fehlermeldung:
Wenn dann nach Ablauf der 10 sec. der zweite Schreiber startet, stößt er auf die unterbrochene Pipe und es kommt zum Folgefehler:java.io.IOException: Pipe broken at java.io.PipedInputStream.read(Unknown Source) at pipe.Leser.run(Pipe.java:19)
java.io.IOException: Read end dead at java.io.PipedInputStream.checkStateForReceive(Unknown Source) at java.io.PipedInputStream.receive(Unknown Source) at java.io.PipedOutputStream.write(Unknown Source) at pipe.Schreiber.run(Pipe.java:38)
Die Pipe scheint sich den Thread zu merken, der einmal Daten geschrieben hat. Sollte dieser irgendwann beendet sein, gibt es den genannten Fehler. Dabei wird nicht beachtet, dass eventuell von anderen Threads noch Daten kommen könnten.
Hat jemand einen Tipp für mich, wie ich das Programm ändern könnte, damit es fehlerfrei läuft?
Nach Möglichkeit möchte ich den OutputStream im Schreiber und den InputStream im Leser beibehalten. Wie oben schon genannt, kann ich die Daten dann nicht nur lokal, sondern auch innerhalb eines Netzwerks zwischen zwei verschiedenen Computern austauschen.
Gibt es vielleicht Alternativen für diese Pipe?
Oder könnte man eine Klasse dazwischen schalten, die meine Daten fehlerfrei durchleitet? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
fuerderer schrieb:
Wenn diese zwei Schreiber aber zeitversetzt laufen, kommt es zur Fehlermeldung. Der erste Schreiber läuft los, sendet sein Byte und beendet sich. Dann sollte 10 sec. später der zweite Schreiber starten und sein Byte ebenfalls senden.
Die Threads beenden sich nicht.
Thread.sleep(10000);
Welcher Thread soll 10s schlafen?
Ich würde das ganze mit Sockets schreiben, wenn es im Netzwerk laufen soll. Ist wahrschlich, aber nur meine eigene Art da ran zu gehen, weil ich bisher mehr mit Sockets gemacht habe.
-
Hallo,
Du könntest eine Weiterleitungs-Klasse machen, die in einem Thread läuft und zwischen deinen wechselnden Threads und der Pipe sitzt. http://stackoverflow.com/questions/1866255/pipedinputstream-how-to-avoid-java-io-ioexception-pipe-broken hier wird genau dieses Problem behandelt.
Das hier ist der entsprechende Code und stammt aus dem angegebenen Link.
final PipedInputStream pin = getInputStream(); final PipedOutputStream pout = getOutputStream(); final CountDownLatch latch = new CountDownLatch(1); InputStream in = new InputStream() { @Override public int read() throws IOException { return pin.read(); } @Override public void close() throws IOException { super.close(); latch.countDown(); } }; OutputStream out = new OutputStream(){ @Override public void write(int b) throws IOException { pout.write(b); } @Override public void close() throws IOException { while(latch.getCount()!=0) { try { latch.await(); } catch (InterruptedException e) { //too bad } } super.close(); } }; //give the streams to your threads, they don't know a latch ever existed threadOne.feed(in); threadTwo.feed(out);
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage