Bytes aus Socket lesen

  • Themenstarter Themenstarter jessy
  • Beginndatum Beginndatum
J

jessy

Gast
Hallo,

ich habe nun schon wirklich alles versucht und weiß nicht woran es liegt. Folgende Codezeile:

... while((readByteCount = socket.getInputStream().read(bArr)) != (-1)) ...

Hier belibt das Programm hängen, egal wie ich es drehe und wende. Kann mir jemand helfen?


Viele Grüße
 
'hängen bleiben' ist ein dehnbarer Begriff

richtig ist, dass das Lesen mglw. blockiert wie auch ein Lesen aus der Konsole, bis der Socket geschlossen wird,
vorher wirst du jedenfalls kein -1, das Zeichen für Ende des Streams, bekommen

wenn der Sender alles sendet und den Socket gleich schließt kann der Client sowas machen,
ansonsten nach Protokoll darauf achten, wann wieviel kommt bzw. damit leben dass es ein träger Thread ist, der Pause macht

----

ich denke dabei immer an zweistufige Variante: ein Thread schaut die ganze Zeit nach und ist sonst blockiert, ein zweiter Thread kann arbeiten und ab und zu evtl. auf fertige Ergebnisse des ersten schauen, damit arbeiten oder sonst weitermachen,

vergleiche Schmiere stehen beim Einbruch 😉

vielleicht hilft auch noch die available()-Methode des Streams, aber die sagt möglicherweise nichts aus ohne selber nachschauen zu müssen, ergo blockiert, dreht sich im Kreis, irgendjemand muss schon warten
 
Zuletzt bearbeitet von einem Moderator:
Hallo und danke für deine schnelle Antwort. Ich verstehe leider deinen letzten Satz nicht: "ansonsten nach Protokoll darauf achten, wann wieviel kommt bzw. damit leben dass es ein träger Thread ist, der Pause macht". Was ist ein Träger-Thread? Ist es nicht möglich bytes über eine persistente Verbindung zu senden?
 
Das heißt, wenn ich jetzt beispielsweise einen HTTP-Server implementieren wollte, samt Keep-Alive, wäre das in Java nicht möglich?
 
Also ich werde noch verrückt. Ich möchte doch einfach nur ein paar Bytes an einen Server schicken und der soll sie wieder zurück zum Client schicken. Ist das in Java nicht möglich? Zuerst muss man den Server und dan den Client testen. Kann mir jemand sagen, warum das read(), egal wie ich es drehe und schiebe nichts liest bzw. was ich hier ändern muss?

Viele Dank im Voraus 🙂

Hier mal mein kompletter Code:
Code:
import java.io.*;
import java.net.*;

public class AdvancedEchoServer implements Runnable {
	private int port;
	private ServerSocket serverSocket;
	
	public AdvancedEchoServer(int port) {
		this.port = port;
		try {
			this.serverSocket = new ServerSocket(port);
		} catch (Exception e) {
			System.out.println("error while initializing server");
		}
		System.out.println("started server on port " + port);
	}
	
	public void run() {
		System.out.println("server is waiting for clients");
		try {
			Socket socket = serverSocket.accept();
			System.out.println("client has connected to server");
			
			BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
			BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
			
			byte[] bArr = new byte[1024]; 
			int readByteCount;
			ByteArrayOutputStream bOut = new ByteArrayOutputStream();
			while((readByteCount = socket.getInputStream().read(bArr, 0, 1024)) != (-1)) bOut.write(bArr, 0, readByteCount);
			bOut.flush();
			byte[] readBytes = bOut.toByteArray();
			System.out.println("SERVER:" + new String(readBytes));
			
			out.write(readBytes);
			out.flush();
			
			in.close(); out.close(); bOut.close();
		} catch (IOException e) {
			System.out.println("error while server was running");
		}
	}
	
	public static void main(String[] args) {
		new Thread(new AdvancedEchoServer(8082)).start();
	}
}

Code:
import java.io.*;
import java.net.*;

public class ClientTester {
	private Socket socket;
	
	public ClientTester(String msg) {
		try {
			socket = new Socket(InetAddress.getLocalHost(), 8082);
			
			BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
			BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
			out.write(msg.getBytes()); out.flush();
			
			ByteArrayOutputStream bOut = new ByteArrayOutputStream();
			int readByteCount;
			byte[] bArr = new byte[1024];
			while((readByteCount = socket.getInputStream().read(bArr, 0, 1024)) != (-1)) {
				bOut.write(bArr, 0, readByteCount);
			}
			System.out.println("2");
			bOut.flush();
			
			System.out.println("CLIENT: " + new String(bOut.toByteArray()));
			
			in.close(); out.close(); bOut.close();
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		new ClientTester("Das ist ein Test");
	}
}
 
siehe mein Link mit available() und nur so viel einlesen, das 'könnte' eine Lösung sein,
aber bedenke auch immer, dass hier verschiedene Prozesse zeitlich zusammenspielen,

wer sagt, dass alle Daten schon da sind wenn available() ausgeführt wird, wenn nicht dann für immer Abbruch?

in deinem Fall könnten die Schleifen zumindest einmal aktiv werden, wenn die ersten bytes da sind,
schreibe System.out.printnl(..)-Log-Ausgaben in die Schleifen,

wenn der Server auch noch ein flush() in der Schleife beim Zurückschicken hätte,
könnte ich mir vorstellen, dass die "Das ist ein Test"-bytes zurückgesendet werden,
selbst wenn danach der Server auf weitere Eingaben wartet

im Client dürften die dann in der Schleife ankommen, wobei danach ebenfalls gewartet wird 😉
kann jetzt aus Zeitmangel nicht mehr testen

-------

was wäre denn dein Wunsch, wann sollte das -1 kommen, nachdem "Das ist ein Test" empfangen wurde,
und zwar weil danach nichts mehr kommt?
wie lange soll der Server darauf warten dass nichts mehr kommt, gar nicht oder z.B. 1 sec?
wenn der Client nach etwas Pause noch was senden will ist der Server schon beim close()?
 
Hallo Slater,

ich hatte zuvor Ausgaben in den Schleifen. Das Problem ist aber, dass keine der Schleifen jemals betreten wird. Sowohl Client auch als Server hängen im read() fest.
 
Java:
while((readByteCount = socket.getInputStream().read(bArr, 0, 1024)) != (-1)) bOut.write(bArr, 0, readByteCount);
			bOut.flush();

Hier ist dein Problem. Nur das "Write" ist IN deiner Schleife. Es ist also nicht sichergestellt, dass auch geflusht wird weil nach dem write direkt wieder gelesen wird.

Edit:
Java:
			while((readByteCount = socket.getInputStream().read(bArr, 0, 1024)) != (-1)) {
				bOut.write(bArr, 0, readByteCount);
			}

Dein Client hängt auch in der While. Beide warten nun ewig auf eine "Antwort" ohne dass irgendwann die Schleife abgebrochen wird.
 
der Server schreibt ja auch nicht direkt an den Client sondern wie der Client in einen ByteArrayOutputStream..
aber eine Log-Meldung bekomme ich beim Server zu sehen
Java:
			while((readByteCount = socket.getInputStream().read(bArr, 0, 1024)) != (-1)) {
				System.out.println("read "+readByteCount+" at server ");
				bOut.write(bArr, 0, readByteCount);
			}

insgesamt ist die Kommunikation freilich schwierig, so wie zwei Menschen am Telefon,
warten, ist der andere fertig, selber sprechen, auflegen?

mit Protokollen, etwa erst Anzahl Bytes vorher senden usw., gehts leichter

auch Web-Browser können hängen wenn manche Seiten ihre Bytes nicht schicken, Seitenaufbau dauert ewig oder klappt nie,
das ist nunmal so, die volle Kontrolle hat man nur wenn man im eigenen Arbeitsspeicher mit 5 int-Variablen jongliert

Timeout kann noch ein interessanter Konfigurationspunkt sein, wie lange warten
 

Neue Themen


Zurück
Oben