Inputstream.read()/readLine() blockiert immer

Status
Nicht offen für weitere Antworten.

Uhm

Mitglied
Meine Frage kurz formuliert:
Wie überprüfe ich ob im Inputstream etwas Neues drinnen ist, damit ich dann .read() im gegenteiligen Fall überspringen kann?

Lang:
Also ich seh im Moment keinen Ausweg: In zb. einem Chat muss ich doch pro Frame einmal nachsehen was im Inputstream geliefert wurde, und das dann auslesen. Nur wird natürlich nicht 1mal pro Frame etwas geliefert, also hängt alles - was völlig inakzeptabel ist.
Jetzt hab ich die Methode availabe() gefunden die mir die Anzahl der Bytes liefern soll, die ich bis zum nächsten Blockieren ungefährdet lesen kann. Aber in der Doku steht:
"The available method for class InputStream always returns 0.
This method should be overridden by subclasses. "

Subklassen wie BufferedReader oder InputStreamReader haben aber keine available() Methode. Sagt jetzt bloß nicht dass ich mir selbst einen Reader schreiben muss!

Achja, außerdem dreht mein PC irre auf wenn das Programm gestartet wird, ich hab aber keine rechenintensiven Tasks...das ist auch vom Blockieren nehm ich an oder?
 

Schandro

Top Contributor
Subklassen wie BufferedReader oder InputStreamReader haben aber keine available() Methode.
^^ wenn sie Subklassen von InputStream sind erben sie doch alle Methoden von InputStream, also auch aviable().
Es kann höchstens sein das sie es auch nicht richtig überschreiben.

Für den Rest müsstest du ein bisschen Code posten.
 

Uhm

Mitglied
Du hast recht, meine Streambeispiele waren gar keine Unterklassen. Aber selbst in den Unterklassen steht in available nur:
"This method simply performs in.read() and returns the result."
Was im Endeffekt wieder nicht die gewünschte Funktionalität bietet...

Java:
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
OutputStream os = cs.getOutputStream();
String line = br.readLine(); <--blockiert eeeewig da auf dem anderen PC ebenfalls read() aufgerufen werden muss und ewig blockiert. Das soll einfach übersprungen werden wenn nichts drinnen ist!
 

Schandro

Top Contributor
starte doch einfach einen eigenen Thread, der immer in.read() aufruft und jedesmal, wenn irgendein Signal geschickt wird, das die aktuelle Nachricht zuende ist, es an irgendwas weiterleitet und dann weiter in.read() aufruft.
 

Uhm

Mitglied
Ahh, einen eigenen Thread extra nur für eine Methode praktisch? Ist es gängig sowas zu machen? Wie man merkt bin ich ein Anfänger, deswegen frag ich :oops:
Klingt auf jeden Fall sehr gut, danke. Dann gibt mir der Thread praktisch ständig meine Werte zurück, und wenn null/-1/ungültig zurückkommt, beachte ich das einfach nicht. Sooo.. jetzt mal rein ins Vergnügen.
 

Noctarius

Top Contributor
Oft wenn es um Streams geht ist es ratsam solche Dinge auszulagern (außer du willst nur eben eine Datei lesen oder schreiben).
An manchen Punkten bist du sogar gezwugen es so zu machen (Fernsteuern von Konsolenanwendungen mit Input-, Output- und Errorstream).

Ich würde auch sagen, pack es mal in einen eigenen Thread und benutz das Observer-Pattern um Daten an einen verarbeiteten Thread weiterzureichen.
 

Uhm

Mitglied
Also die Sache funktioniert überhaupt nicht. Der Chat läuft schon so langsam dass mein PC sich aufhängt (wegen der while(true) schleifen glaub ich, aber ich bekomme nach ner Weile out of heap memory Errors), und Strings werden zwar übertragen, aber nur wenn ich mit dem Debugger Thread für Thread abwechselnd durchlaufe. Die pfuschen sich irgendwie gegenseitig rein. Werden Bytes denn nicht im OutputStream gehalten solange bis ich sie rauslese? Ich stell euch die run() Methoden rein, vielleicht seht ihr nen offensichtlichen Fehler...mann, bei solchen Dingen hinterfrage ich immer ob Programmieren wirklich was für mich ist :/
Java:
/* **SERVER** run() method of the ConnectionManager class, which holds all currently connected sockets.*/
while(true)
		{
/* This loops through all sockets in "connectionList" and all threads in "readers" 
and reads and writes string data from the GUI into/from their streams.*/

			for (int i = 0; i < connectionList.size(); ++i)
			try 
			{ 
				Socket cs = connectionList.get(i); 
				
				OutputStream os = cs.getOutputStream();
				
				String line = readers.get(i).getString();
				if (line != null && !line.equals(""))
				{
					byte[] tempBytes = line.getBytes();
					for (int j = 0,counter = i; j < connectionList.size(); ++j,counter=(counter+1)%connectionList.size())
					{// write the data from one client, to all the other clients
						os.write(tempBytes);
					}
					app.appendString(line); // +display them on server
				}
			
			}

Java:
 **CLIENT**

while(running)
		{
			// get string data from the application
			String temp = app.getSentText();
			
			if (!temp.equals("\n") && !temp.equals(""))
			try {
				byte[] buffer = temp.getBytes();
				os.write(buffer, 0, buffer.length);
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			// receive server data and write to client GUI
			String line = reader.getString();
			if (line != null && !line.equals("") && !line.equals("\n"))
			{
				this.app.appendString(line);
			}
			
			
		}

Eure vorgeschlagene Readerklasse. Jeder Socket hat so einen Readerthread, der ewig läuft und ständig vom Inputstream nachliest.
Java:
public class ReaderThread implements Runnable {

	private Socket sc;
	private String readString;
	public ReaderThread(Socket socket)
	{
		this.sc = socket;
		readString = new String();
	}
	public void run() 
	{
		while (true)
		{
			InputStream is;
			try {
				is = sc.getInputStream();
				InputStreamReader isr = new InputStreamReader(is);
				BufferedReader br = new BufferedReader(isr);
				readString += br.readLine();
	
			} catch (IOException e) {
				e.printStackTrace();
			}	
		}
		
	}
	public String getString()
	{// return everything that has been read, and reset the "buffer" string to zero characters
		String temp = readString;
		readString = new String();
		return temp;
	}
	
}
 

Schandro

Top Contributor
Es ist (imho) nie sinnvoll das aufzurufen, wenn du einen "leeren" string haben willst, schreib einfach nur
""

readString += br.readLine();
Strings mit dem plus Operator aneinanderzuhängen ist extrem, wirklich extrem Performancefressend sobald es in Schleifen passiert.
€dit: Mach aus readString einen StringBuffer (nicht StringBuilder) und benutz die .append Methode zum dranhängen. StringBuffer ist threadsafe.


Schreib die Zeilen 16 bis 18 außerhalb der unendlichschleife, ansonsten initialisierst du für jede einzelne Zeile die gelesen werden soll immer extra einen neuen BufferedReader und InputStreamReader....
 
Zuletzt bearbeitet:

Uhm

Mitglied
Hab deine Verbesserungen eingebaut, hab aber noch immer 100% Prozessorauslastung. Dafür scheint kein heap overflow mehr zu kommen. Ich kann mir vorstellen warum ich 100% habe, immerhin versucht der Prozessor eine while(true) Schleife sooft wie möglich aufzurufen. Sooft wie möglich ist nunmal immer 100%... gibts eine Alternative zu while(true) und trotzdem einen ständig im Hintergrund laufenden Thread zu haben?
@sparrow:
Die innere for-Schleife fängt bei dem aktuellen Socket an und iteriert solange (auch über das Ende der Liste, deswegen die Modulooperation) bis alle Clients/Sockets einmal angeschrieben wurden mit dem neuen String.
Zb.:
Socket an der Stelle 3 ist aktuell. Liste hat 5 Mitglieder. Dann schicke ich zuerst den String an Socket3, dann 4, 5, dann 1,2 und aus. Insgesamt schicke ich 5 mal. Bisschen allgemeiner gesagt: ich schicke solange bis "j" 5 erreicht hat.
 

Uhm

Mitglied
Nein, beide gleich. Anscheinend ist es ein Problem in der GUI, sonst gibts ja keine andere Erklärung. Hab bemerkt dass schon bevor ich den geringsten Netzwerkcode starte, es auf 100% springt. Glaub echt dass die while() Schleifen das Problem sind, denkt ihr nicht? Hier ist wie ich das ganze aufziehe:
Java:
**MAIN Methode**
// the user has to define port, host and application type before continuing
GUI app = new GUI();
new Thread(app).start();
while (!app.isInitialized());
if (app.applicationType.equals("Server")
{
. . .
}else
...
Java:
**ein paar relevante GUI Methoden: **
public void run() 
{
		createAndShowGUI(); // create labels, buttons, frames..
		while (true);
}
public void actionPerformed(ActionEvent arg0) 
{
if (arg0.getActionCommand() == "enter")
		{
			sentMessage = textField.getText();
			textField.setText("");
		}
}
public String getSentText()
	{
		// clear it, so we dont send one message possibly twice
		String temp = sentMessage + "\n";
		sentMessage = "";
		return temp;
	}
	public void appendString(String append)
	{
		textareaText = append;
		textArea.append(textareaText + "\n");
	}

Übrigens kann ich denk ich, bestätigen dass die Threads sich gegenseitig stören. Ich hab testweise den übertragenen String nie gelöscht, und einfach immer wieder dranhängen lassen (mit append)...und siehe da: das ganze Fenster war in nem Bruchteil einer Sekunde voll mit meinem Testwort. Nur versteh ich nicht wie sie sich stören können, immerhin wird korrekt in den Outputstream reingeschrieben, das hab ich überprüft.
ajo und in der inneren for Schleife fehlt
Java:
os = connectionList.get(counter).getOutputStream();
 

sparrow

Top Contributor
Moment, also erstmal:
jede while-Schleife die ungebremst durchläuft verbraucht immer alle Resourcen, da ja nie eine Pause eingelegt wird. Selbst wenn die Schleife leer ist würden alle Resourcen dafür aufgebraucht werden die leere Schleife immer wieder zu durchlaufen.

Ich würde auf dem Server wie folgt vorgehen:

Klasse 1 -> Initialisiert ggf. die GUI und initialisiert und die Sockets aufbaust
Sockets werden, wie du es schon hast, in einer Collection verwaltet. Ich würde hier auf eine HashMap setzen mit dem Benutzernamen als Key. So könnte man auch mal flüstern weil man einfach an den Benutzernamen kommt.
Das wo die Sockets lauschen sollten jeweils einzelne Threads sein. Die verbrauchen ja eben nicht die vielen Resourcen weil sie blockieren bis etwas herein kommt.

So, und dann eben nicht einen Thread immer durchlaufen lassen, sondern eingehende Nachrichten in einer Collection speichern und einen "sendeThread" immer schlafen lassen und bei einer eingehenden Nachricht aufwecken.
Dieser durchsucht dann die Colection mit den Nachrichten und sendet alle verfügbaren Nachrichten an alle Adressaten.
 

Uhm

Mitglied
Also warum ich einen extra Sendethread brauche, ist mir nicht klar. Die Nachrichten mal eben in den Outputstream zu schreiben dauert ja nicht lange, und wird sowieso per Knopfdruck, (also bei Druck auf Enter im Textfeld) gemacht bzw. gleich nachdem etwas eingelesen werden konnte.
Und while(true) schleifen brauch ich trotzdem fürs Einlesen von Daten, ein Thread hat ja keinen Rückgabewert. Deswegen muss ich ständig 1mal pro Frame überprüfen ob der Lesethread gerade etwas gelesen hat oder nicht. => resultiert wieder in 100% CPU :(
 
Zuletzt bearbeitet:

sparrow

Top Contributor
Uhm;515892Deswegen muss ich ständig 1mal pro Frame überprüfen ob der Lesethread gerade etwas gelesen hat oder nicht. => resultiert wieder in 100% CPU :([/QUOTE hat gesagt.:
Wieso pro Frame? Programmierst du ein Spiel?
Falls nicht, und du eine SWING-Oberfläche hast, brauchst du nicht jede Sekunde nachschauen.
Wenn du z.B. eine bufferedReader mit .readLine() verwendest blockiert der Thread doch sowieso so lange bis eine vollständige Line vorliegt. Demnach ist es einfacher und schonender für die Resourcen wenn nach einer komplett empfangenen Line dafür sorgt, dass andere Programmteile darüber informiert werden (notice) anstatt ständig zu fragen (polling) ob eventuell neue Informationen vorliegen.
 

ModellbahnerTT

Bekanntes Mitglied
Völlig falsches vorgehen, schau in die FAQ, da ist ein Beispiel für einen Chat, oder denkst du wirklich es ist sinnvoll ununterbrochen zu schauen ob der benutzer was in das textfeld eingibt und das zu senden (dass dann 100x mal das selbe gesendet wird ist dir nicht in den Sinn gekommen?) anstatt auf Befehl (knopf/enter gedrückt) EIN mal den text aus dem feld zu senden?
 

Uhm

Mitglied
oder denkst du wirklich es ist sinnvoll ununterbrochen zu schauen ob der benutzer was in das textfeld eingibt und das zu senden
Einfacher zu programmieren wärs auf jeden Fall, ich nehm an dass man noch irgendwie mit nem Timer einstellen könnte dass nur jede 0.5 Sekunden nachgeschaut werden soll.

Danke Leute, ich hab es dank eurer Hilfe doch tatsächlich noch zum Laufen gebracht. Das Problem was ich jetzt habe ist "nur", dass wenn sich ein Client rausklingt, sich alles aufhängt weil "Connection reset" Exceptions ohne Ende gerufen werden.
Ich kapier nur nicht wo genau das Problem des Programms jetzt ist. Es soll einfach weitermachen ohne diesen Socket. (dazu muss ich jetzt sagen dass ich von Exceptions wenig Ahnung habe... ich weiß nur dass man irgendwie abfangen kann, aber ich klick immer nur auf "generate try and catch" :autsch:)

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at ue4.ReaderThread.run(ReaderThread.java:46)
at java.lang.Thread.run(Unknown Source)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Eigener InputStream, Hilfe bei read-Methode Java Basics - Anfänger-Themen 6
A Wie nutze ich InputStream? Java Basics - Anfänger-Themen 7
K Warum wird hier nur etwas in eine txt Datei geschrieben und nicht in alle drei (InputStream/OutputStream/Reader/Writer) Java Basics - Anfänger-Themen 1
I Dateigröße von einem InputStream oder byte[] bekommen Java Basics - Anfänger-Themen 2
berserkerdq2 inputstream und bufferedwirter /outputstream und bufferedwriter Java Basics - Anfänger-Themen 9
T Bluetooth, Inputstream Java Basics - Anfänger-Themen 0
I InputStream beim zweiten Mal fehlerhaft Java Basics - Anfänger-Themen 10
B Inputstream in file schreiben? Java Basics - Anfänger-Themen 23
B InputStream / OutputStream / PipedOutputStream und managedExecutorService Java Basics - Anfänger-Themen 3
B java.io.OutputStream zu java.io.InputStream konvertieren Java Basics - Anfänger-Themen 18
B Hilfe bei InputStream To File Java Basics - Anfänger-Themen 22
B InputStream (PDF) nach Image (PNG / JPG) konvertieren? Java Basics - Anfänger-Themen 2
B Konvertieren: Outputstream zu Inputstream Java Basics - Anfänger-Themen 13
J Was genau macht die Methode close() im InputStream? Java Basics - Anfänger-Themen 5
E InputStream im Servlet wirft Exception Java Basics - Anfänger-Themen 5
D InputStream parsen und als Bilddatei abspeichern Java Basics - Anfänger-Themen 1
G Input/Output InputStream gibt nicht die Korrekten Werte aus Java Basics - Anfänger-Themen 10
T Datentypen InputStream to list of Int (or similar) Java Basics - Anfänger-Themen 4
P bytes aus einem InputStream zählen Java Basics - Anfänger-Themen 2
P InputStream eines Musik-Streams abspielen Java Basics - Anfänger-Themen 2
I Resize Image - Einlesen von InputStream Java Basics - Anfänger-Themen 3
T Input/Output Exception bei einem InputStream Java Basics - Anfänger-Themen 2
W ProcessBuilder InputStream in Array speichern Java Basics - Anfänger-Themen 3
K InputStream erstellen Java Basics - Anfänger-Themen 4
B Input/Output Data / Buffer / File Outstream Inputstream Java Basics - Anfänger-Themen 2
L Webservice soll InputStream übergeben bekommen Java Basics - Anfänger-Themen 7
C InputStream Java Basics - Anfänger-Themen 2
O Input/Output Fragen zum InputStream Java Basics - Anfänger-Themen 7
E Input/Output Relativer Bild-Pfad für InputStream Java Basics - Anfänger-Themen 5
G Frage zu InputStream? Java Basics - Anfänger-Themen 11
E Socket InputStream "terminiert" nicht Java Basics - Anfänger-Themen 4
E Input/Output Inputstream während der Laufzeit füllen Java Basics - Anfänger-Themen 2
A Frage zu Beispiel eines Dekorierers von InputStream Java Basics - Anfänger-Themen 4
B Input/Output InputStream (JSch) in OutputStream (Blob) überführen Java Basics - Anfänger-Themen 8
P Input/Output InputStream Listener? Java Basics - Anfänger-Themen 7
M Eigener InputStream will nicht mit BufferedReader Java Basics - Anfänger-Themen 3
S Input/Output Neuen InputStream System.in setzen Java Basics - Anfänger-Themen 11
A InputStream gibt nur jede 2te Zeile aus Java Basics - Anfänger-Themen 7
J InputStream FTP Java Basics - Anfänger-Themen 8
brunothg Inputstream zu Filechannel Java Basics - Anfänger-Themen 6
K StringWriter/String nach InputStream konvertieren Java Basics - Anfänger-Themen 3
Benji0815 Inputstream aus Konsole in JTextArea Java Basics - Anfänger-Themen 14
A Problem mit InputStream Java Basics - Anfänger-Themen 4
bastiann Kann man Inputstream nur auf ein Zeichen anwenden? Java Basics - Anfänger-Themen 5
S Problem mit url, inputStream und bytes beim Quellcode laden. Java Basics - Anfänger-Themen 6
G Kompletten InputStream der Kommandokonsole ausgeben Java Basics - Anfänger-Themen 8
G InputStream aufrufen, ändern und zurück geben Java Basics - Anfänger-Themen 2
W Zeichen ersetzen im InputStream Java Basics - Anfänger-Themen 3
N String vom InputStream in TextArea übertragen Java Basics - Anfänger-Themen 6
A Frage zu Puffergröße bei InputStream Java Basics - Anfänger-Themen 9
G in einem inputstream auf " " abfragen? Java Basics - Anfänger-Themen 3
M Datei speichern mittels InputStream Java Basics - Anfänger-Themen 13
P InputStream in Byte-Array speichern Java Basics - Anfänger-Themen 2
G String in InputStream umwandeln? Java Basics - Anfänger-Themen 8
M Auslesen eines InputStream Java Basics - Anfänger-Themen 4
M Problem mit InputStream Java Basics - Anfänger-Themen 7
S Probleme mit InputStream- Rückgabe Java Basics - Anfänger-Themen 4
I InputStream von Konsole abfangen Java Basics - Anfänger-Themen 6
G InputStream im finally-Block schließen Java Basics - Anfänger-Themen 7
K InputStream? Java Basics - Anfänger-Themen 3
S Sockets and InputStream Java Basics - Anfänger-Themen 2
M InputStream einer Socketverbindung funktioniert nicht Java Basics - Anfänger-Themen 19
M Byte InputStream zu Zeichenformat Unicode bzw String konvert Java Basics - Anfänger-Themen 5
R InputStream erstellen, der aus String liest Java Basics - Anfänger-Themen 8
R ENTER in InputStream nicht lesen Java Basics - Anfänger-Themen 4
G InputStream auslesen und zurückschreiben Java Basics - Anfänger-Themen 9
R BufferedReader <-> InputStream Java Basics - Anfänger-Themen 3
R Suche geeignetes InputStream Java Basics - Anfänger-Themen 2
D InputStream -> Image Java Basics - Anfänger-Themen 6
M String zu InputStream/InputSource Java Basics - Anfänger-Themen 2
S Problem mit InputStream / flush() / BufferedReader Java Basics - Anfänger-Themen 19
C Aus ein Image-Objekt einen InputStream generieren? Java Basics - Anfänger-Themen 6
J InputStream in String umwandeln Java Basics - Anfänger-Themen 5
J InputStream ist null Java Basics - Anfänger-Themen 7
P InputStream, BufferedString Java Basics - Anfänger-Themen 3
M NullPointerException: Cannot read the array length because "this.Kinder" is null Java Basics - Anfänger-Themen 1
T IOStreams read(byte[]b) methode Java Basics - Anfänger-Themen 2
josfe1234 Hilfe access denied ("java.io.FilePermission" " " "read") Java Basics - Anfänger-Themen 12
C System.in.read() Boolsche Werte vergleichen Java Basics - Anfänger-Themen 8
J Variablen Komsiche System.in.read() return-value? Java Basics - Anfänger-Themen 3
N Threads Read-Modify-Write Problem bei Multithreading (philosopher dining problem) Java Basics - Anfänger-Themen 5
V FileInputStream - read() Java Basics - Anfänger-Themen 2
W Input/Output System.in.read erzeugt nicht, was ich will Java Basics - Anfänger-Themen 1
C Input/Output System.in.read() gibt nicht -1 zurück? Java Basics - Anfänger-Themen 3
F Input/Output Blocking file read erzeugen Java Basics - Anfänger-Themen 0
G Thread stoppen mit System.in.read() Java Basics - Anfänger-Themen 13
G comport read Java Basics - Anfänger-Themen 3
B Frage zur Effizienz von read und read(byte[]) Java Basics - Anfänger-Themen 23
S Java für Anfänger: Probleme mit read() Java Basics - Anfänger-Themen 20
G Input/Output System.in.read & Scanner Java Basics - Anfänger-Themen 2
L Fehler bei "read" ? Java Basics - Anfänger-Themen 4
R ImageIO.read Fehler Java Basics - Anfänger-Themen 4
K Input/Output read/write Java Basics - Anfänger-Themen 15
B Threads Interrupt während Socket.read()? Java Basics - Anfänger-Themen 3
G Problem mit Image.IO.read( File ) Java Basics - Anfänger-Themen 3
C FileInputStream read() Overflow Problem Java Basics - Anfänger-Themen 6
W Koordinaten mit System.in.read() setzen Java Basics - Anfänger-Themen 2
W file read write crash Java Basics - Anfänger-Themen 2
L Read.java Java Basics - Anfänger-Themen 4
F FileReader Methode Read() int? Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben