Socket HTTP-Request führt zu Endlosschleife

bit

Mitglied
Hallo zusammen,

ich habe einen sehr simplen Web-Server, der lediglich einen Request entgegennimmt und diesen als Antwort an den Browser zurückschickt ("Echo").

Das macht er aber nur, wenn ich den Request explizit auf die Leerzeile im HTTP-GET abfrage. Falls die Abfrage auskommentiert wird (s. Quellcode Zeile 22), bleibt der Server in einer Endlosschleife, irgendwo in der Klasse BufferedReader, Methode readLine (genauer in der Methode fill()).

Sollte readLine nicht prinzipiell irgendwann vom Stream mit null zurückkehren, auch wenn ich die Leerzeile nicht explizit abfange?


Java:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class VerySimpleWebServer {
	public static void main(String[] args) {
      System.out.println("VerySimpleWebServer gestartet");
		try {
			ServerSocket server = new ServerSocket(8888);
			Socket client = server.accept();
			BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
	      StringBuffer request = new StringBuffer();
	      while(true) {
            String line = br.readLine();
            System.out.println(line);
            if(line != null) {
            	request.append(line+"\n");
               if(line.length() <=0) break; // ohne bleibt der Server in Endlosschleife
            } else
               break;
	      }
	      System.out.println(request);
			bw.write(request.toString());
			bw.flush();
			bw.close();
			client.close();
			server.close();
		} 
		catch (Exception e) {
			System.err.println("!"+e.toString());
			e.printStackTrace();
		}
      System.out.println("VerySimpleWebServer beendet");
	}

}
[/Java]
 
die readLine vom Socket ließt solange, bis etwas ankommt (blockierend).
Wenn nichts ankommt bleibst du halt ewig darin stecken. Rausfliegen kannst du dort nur, indem die Verbindung geschlossen wird. Das wird aber nicht passieren, da dein Partner (Browser) ja eine Antwort erwartet (evtl. fliegst du nach 30-60 Sekunden raus wenn der Browser nen Timeout meldet). Du musst dir also selbst gedanken machen Wann und Ob du die readLine nutzt.
 
aha. Tatsächlich.
In der Methode fill() im BufferedReader bleibt der Server tatsächlich an der Stelle

n = in.read(cb, dst, cb.length - dst);

stehen (mit Debugger geprüft). D.h. er wartet hier auf die nächsten Zeichen.

Der Stream bleibt natürlich noch offen weil die Verbindung vom Socket/Browser noch für die weitere Kommunkation offen ist. Und somit gibt es auch kein "End of Stream", der ein null in readLine() zurückliefern würde.

Ich hatte iregndwie angenommen, das der Browser nach dem Absenden des GET den Stream schließt. Aber das ist natürlich nicht richtig (ich hatte meine MiniServer vorher auch mit einem MiniClient getestet, der nach dem Absenden einer Anfrage ein shutdownOutput() auf dem Stream durchgeführt und somit ein EOF gesendet hatte.

Nochmals aha.
Und vielen Dank für die prompte Antwort!
 
Hi,

probier doch mal:

Java:
String line = "";
 while ((line = br.readLine()) != null) {
            request.append(line+"\n")
            System.out.println(line);
          }
 
Zuletzt bearbeitet:
ihr wisst aber schon das es Socket.setSoTimeout(int) gibt oder ? zumindest sollte man das wissen wenn man in der lage ist die APi-DOC zulesen ...
 

Zurück
Oben