InputStream einer Socketverbindung funktioniert nicht

Status
Nicht offen für weitere Antworten.
M

Marcel22

Gast
Ich baue eine Socketverbindung zu einem Server auf und sende ihm Daten zu.

Anschließend sendet mir der Server Daten zurück. Diese Daten werden bei mir jedoch nicht ausgegeben.

Es wird eine

SocketException: Socket is closed
at java.net.Socket.getInputStream(Unknown Source)
geworfen.

Kann mir vielleicht jemand sagen, woran dieses liegt ?

Anbei der Quellcode:

Code:
Socket server = new Socket("192.168.2.20", 80);
DataOutputStream outstream = new DataOutputStream(new BufferedOutputStream(server.getOutputStream()));

String message="test\r\ntest\r\n";

int lengthString = message.length();

String header = "POST / HTTP/1.1\r\n" + "Content-Type: text/xml\r\n".....

String packet = header + message;

outstream.writeUTF(packet);
outstream.close();
server.close();
BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream()));
System.out.println(br.readLine());
br.close();

Kann es sein, dass das Socket geschlossen wird, wenn ich den Stream schließe ?
 

Ilja

Bekanntes Mitglied
nicht nur das!
du hast auch die verbindung gekappt, bevor zu daraus lesen willst -.-
server.close();
 
M

Marcel22

Gast
Ja stimmt. Kam noch vom ganzen hin und her kopieren :roll:

Aber auch wenn ich die Socketverbindung nicht schließe, wird weiterhin die gleiche Exception geworfen.

Woran kann dies denn noch liegen ?
 
M

marcel22

Gast
Ok ich habe es nun hinbekommen. Anstatt von outstream.close() habe ich flush() verwendet. Wußte nicht, dass er bei close auch die Socketverbindung schließt.

Schönen Dank auch :)
 

Ilja

Bekanntes Mitglied
hö?

flush() bewirkt, dass der buffer in den stream geleer/ausgegeben wird! ...das hat NIX mit close zutun -.-
 
M

Marcel22

Gast
Tjoa mich wunderts auch ein wenig, ist für mich aber die einzigst logische Erklärung. Wenn ich es wieder mit close() probiere bekomme ich SocketClosed Exception

Aber wie kann ich denn alle Daten am Besten auslesen.

Ich bekomme am Anfang einen Http-Header, dann folgt ein Zeilenumbruch und dann kommt die eigentliche Nachricht im XML Format.

Ich habs grad mal folgendermaßen probiert:

Code:
BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream())); 
int ch;
		StringBuffer data = new StringBuffer();
		while((ch = br.read()) != -1) {
			if(ch != '\n'){
			data.append((char)ch);
			}else{
			System.out.println(data.toString());
			data = new StringBuffer();
			}
		}

Dann bekomm ich halt die Zeilen ausgegeben, aber ich schaffe es nicht sie in einen String oder Strinbuffer einzufügen, so dass ich diesen später parsen kann.

Hat dort jemand eine Idee ?
 

Mag1c

Top Contributor
Hi,

wenn du schon einen BufferedReader hast, warum benutzt du ihn dann nicht ?

Code:
String line;
while ((line = br.readLine()) != null) {
    System.out.println(line);
    data.append(line);
}

Gruß
Mag1c
 
M

Marcel22

Gast
Ja ich habs jetzt mit readLine() gemacht.

Code:
	public void createXML() throws IOException {
		Socket server = new Socket("192.168.0.123", 80);

		System.out.println("connected to " + server.getInetAddress());
		DataOutputStream outstream = new DataOutputStream(
				new BufferedOutputStream(server.getOutputStream()));

		String message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
				+ "<SessionLogin>\r\n" + "<user>" + user + "</user>\r\n"
				+ "<password>" + password + "</password>\r\n"
				+ "</SessionLogin>";

		int lengthString = message.length();

		String header = "POST / HTTP/1.1\r\n" + "Content-Type: text/xml\r\n"
				+ "User-Agent:xy\r\n" + "Host:12345678\r\n"
				+ "Content-Length:" + lengthString + "\r\n"
				+ "Connection: Keep-Alive\r\n"
				+ "Cache-Control: no-cache\r\n\r\n";

		String packet = header + message;
		System.out.println(packet);

		outstream.writeUTF(packet);
		outstream.flush();

		BufferedReader br = new BufferedReader(new InputStreamReader(server
				.getInputStream()));
		StringBuffer data = new StringBuffer();
		String line;
		while ((line = br.readLine()) != null) {
			System.out.println(line);
			data.append(line);
		}
		br.close();
	}

Das ist jetzt quasi mein kompletter Quelltext. Das Problem ist momentan, dass ich nicht alle Daten bekomme. Nach der Leerzeile wird noch eine Zeile ausgespuckt und das war es dann. Außerdem wird das Programm dauerhaft ausgeführt, auch wenn ich die Socketverbindung am ende wieder trenne. Woran können diese beiden Sachen liegen ?

Oder gibt es generell einen besseren Weg das ganze umzusetzen ?
Serverseitig muss ich mir auf jeden Fall alles manuell zusammenbasteln(Header + XML Nachricht), da auf dem Server kein Java Tool läuft.

PS: Schönen Dank für die schnellen Antworten :)
 

Mag1c

Top Contributor
Hi,

achso, es geht um einen HTTP-Request. Dann geht das mit der while-Schleife so nicht. Es gibt zwei Möglichkeiten HTTP-Antworten zu empfangen.

1. der Header enthält ein "Content-Length:" Attribut. Dann ist es einfach, man liest einfach entsprechend viele Daten ein.

2. wenn 1. nicht geht, muß man soviel lesen, wie was kommt. Und wenn dann nichts mehr kommt, müsste man noch einen Timeout abwarten, ehe man davon ausgehen kann, daß da nichts mehr kommt. (Echt blöd ;) )

Gruß
Mag1c
 
M

Marcel22

Gast
Genau. Ich hatte mir es eigentlich auch vorgenommen, dass ganze über Content Length zu machen.
Wie kann ich aber denn nach diesem Wert parsen ?

Ein anderes Problem ist:

Code:
		while ((line = br.readLine()) != null) {
			System.out.println(line);
			data.append(line);
		}

Dies scheint eine Endlosschleife zu sein. Er geht dort nicht mehr raus, obwohl er eigentlich alle Daten liest.

Dies ist die letzte Zeile die er bekommt: "<sessionloginreply>\r\n"
Er versucht aber scheinbar weiterhin Daten einzulesen, bzw. readLine() kann danach ja immer noch nicht = null sein, sonst würde er ja die Schleife verlassen.

Irgend eine Idee woran das liegen könnte =?

Und ich versteh auch nicht warum er überhaupt die Nachricht ließt, da der Header von der Nachricht durch eine Leerzeile getrennt ist. Dann sollte er ja eigentlich dort aufhören.... ?
 

Mag1c

Top Contributor
Hi,

nein, Leerzeile ist Leerzeile (also "") und nicht null. Du mußt schon selbst erkennen, wann der Header zuende ist (z.B. durch line.length() == 0). In diesem Fall verläßt du die Schleife, kannst den bis hier geladenen Teil (den Header) nach "Content-Length:" parsen (du könntest natürlich auch schon beim lesen des Headers nach dem Attribut ausschau halten). Wenn du den Wert dann hast, liest du weiter vom BufferedInputStream (diesmal nicht mehr mit readLine) bis du den gesamten Content geladen hast.

Gruß
Mag1c
 
M

Marcel22

Gast
Mit welcher Mehode kann ich denn dann den restlichen Teil der Nachricht lesen ?
Also mit Angabe von Content-Length halt als Übergabeparameter.

Der BufferedReader bietet mir doch dazu keine Methode an oder hab ich da etwas übersehen ?
 

Mag1c

Top Contributor
Hi,

siehe "read(char cbuf[], int off, int len)"

HttpClient wäre auch eine Möglichkeit.

Gruß
Mag1c
 

AlArenal

Top Contributor
Zumal man bei HttpClient die Möglichkeit hat den Inhalt der Antwort wahlweise als Feld von Zeichen, als InputStream oder als String zu bekommen.
 
M

Marcel22

Gast
Das ist ja alles schön und gut, aber es funktioniert nicht wirklich... weil der Server halt auch nicht über Java eine Verbindung aufbaut und ich dort nur eingeschränkte Möglichkeiten habe, wobei ich ausschließlich eine Socketverbindung über Port 80 herstellen kann. Die Nachrichten werden dann generell von beiden Seiten mittels selbst erzeugten Http Posts versendet.
Dies muss ich serverseitig bspw. auf jeden Fall so machen...

Ich wüßte nicht wie ich meinen Code dahingehend ändern könnte, dass es mit HttpClient funktioniert... ?!?
 

AlArenal

Top Contributor
Schau dir das Beispiel aus dem kleinen Tutorial, das ich verlinkt hatte, mal an:

Code:
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
import org.apache.commons.httpclient.params.HttpMethodParams;

import java.io.*;

public class HttpClientTutorial {
  
  private static String url = "http://www.apache.org/";

  public static void main(String[] args) {
    // Create an instance of HttpClient.
    HttpClient client = new HttpClient();

    // Create a method instance.
    GetMethod method = new GetMethod(url);
    
    // Provide custom retry handler is necessary
    method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
    		new DefaultHttpMethodRetryHandler(3, false));

    try {
      // Execute the method.
      int statusCode = client.executeMethod(method);

      if (statusCode != HttpStatus.SC_OK) {
        System.err.println("Method failed: " + method.getStatusLine());
      }

      // Read the response body.
      byte[] responseBody = method.getResponseBody();

      // Deal with the response.
      // Use caution: ensure correct character encoding and is not binary data
      System.out.println(new String(responseBody));

    } catch (HttpException e) {
      System.err.println("Fatal protocol violation: " + e.getMessage());
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println("Fatal transport error: " + e.getMessage());
      e.printStackTrace();
    } finally {
      // Release the connection.
      method.releaseConnection();
    }  
  }
}

Die Zeilen 31 und 35 kann man mit nem Blick in die JavaDocs von HttpClient ändern, es steht aber auch im Tutorial:

It is vital that the response body is always read regardless of the status returned by the server. There are three ways to do this:

* Call method.getResponseBody(). This will return a byte array containing the data in the response body.
* Call method.getResponseBodyAsString(). This will return a String containing the response body. Be warned though that the conversion from bytes to a String is done using the default encoding so this method may not be portable across all platforms.
* Call method.getResponseBodyAsStream() and read the entire contents of the stream then call stream.close(). This method is best if it is possible for a lot of data to be received as it can be buffered to a file or processed as it is read. Be sure to always read the entirety of the data and call close on the stream.

For this tutorial we will use getResponseBody() for simplicity.

HttpMethodBase (Basisklasse auch von GetMethod) bietet nämlich diese nützlichen Gesellen:

byte[] getResponseBody()
Returns the response body of the HTTP method, if any, as an array of bytes.

InputStream getResponseBodyAsStream()
Returns the response body of the HTTP method, if any, as an InputStream.

String getResponseBodyAsString()
Returns the response body of the HTTP method, if any, as a String.

Schon brauch man sich selbst nicht mehr mit Sockets herumplagen und schauen ob was kommt, was kommt, wo der Content anfängt und wie lang der ist, etc.
 
M

Marcel22

Gast
Ja ich hab mich da vorher auch shcon mit befasst, bin aber zu dem Schluss gekommen, dass ich es so wie ich es nun mache auch ganz gut hinbekomme. Im Moment funktionierts sogar :wink:

Habe grad nur ein Problem mit dem Parsen der XML Nachricht.
Ich parse diese grade mit Stax. Problem ist nur, ich muss ihm dann ja den InputStream übergeben.

Gibt es auch irgendwie eine Möglichkeit einen String nach XML zu parsen ?

Momentan mach ich das folgendermaßen:

Code:
			XMLInputFactory factory = XMLInputFactory.newInstance();
			XMLStreamReader parser = factory.createXMLStreamReader(br);
			while( parser.hasNext() ) {
			    int event = parser.next();
			    switch (event) {
			        case XMLStreamConstants.END_DOCUMENT:
			            System.out.println("END_DOCUMENT");
			            parser.close();
			            break;
			        case XMLStreamConstants.START_ELEMENT:
			            System.out.println("START_ELEMENT: " + parser.getLocalName() );
			            break;
			        case XMLStreamConstants.CHARACTERS:
			            if( !parser.isWhiteSpace() )
			                System.out.println("CHARACTERS: " + parser.getText() );
			            break;
			        case XMLStreamConstants.END_ELEMENT:
			            System.out.println("END_ELEMENT: " + parser.getLocalName() );
			            break;
			        default:
			            break;
			    }
			}


br = BufferedReader, mit dem ich bereits vorher den Http Header und die Content-Length ausgelesen habe. Aber wo soll ich nun in diesem Fall die COntent Length angeben ? Bei dieser Variante scheint er nämlich wieder in der EndlosSchleife zu bleiben und versuchen weitere Daten zu lesen, obwohl keine mher vorhanden sind....
 
M

Marcel22

Gast
So ich habs grad mit nem StringReader versucht, was auch zu funktionieren scheint, allerdings bekomme ich noch eine Exception dabei geworfen :

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: only whitespace content allowed before start tag and not P

Was soll mir das jetzt sagen ? Hab bei google auch nicht wirklich was gefunden...
 

Mag1c

Top Contributor
Moin,

na es steht doch alles da. Hast du mal geschaut, was in dem String drin steckt ?

Gruß
Mag1c
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
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
S Eigener InputStream, Hilfe bei read-Methode Java Basics - Anfänger-Themen 6
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
U Inputstream.read()/readLine() blockiert immer Java Basics - Anfänger-Themen 18
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 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 Ausgabe einer ArrayList ensteht nur als Hashcode, nicht als Objekt Java Basics - Anfänger-Themen 16
D 2 ArrayListen gleich sortieren bzw. eine Liste anhand einer anderen Sortieren Java Basics - Anfänger-Themen 6
ixChronos Letzten 4 Ziffern einer großen Zahl ausgeben Java Basics - Anfänger-Themen 3
P Objekt einer Methode eines anderen Objektes übergeben Java Basics - Anfänger-Themen 5
L Variablenwerte aus einer Methode übergeben Java Basics - Anfänger-Themen 2
E Arrays in einer ArrayList miteinander vergleichen Java Basics - Anfänger-Themen 12
Simon16 Java ArrayListe von einer Klasse sortieren Java Basics - Anfänger-Themen 2
Shadowrunner Variablen Gibt es eine Möglichkeit die Ziffern/Stellen einer Zahl fest zu legen? Java Basics - Anfänger-Themen 3
D remove Object von einer Liste von Obejcts Java Basics - Anfänger-Themen 3
FunkyPhil94 Wert in einer Lambda Funktion erhöhen Java Basics - Anfänger-Themen 3
T Aufruf der Methode einer Oberklasse, wenn sie in der Unterklasse überschrieben ist. Polymorphie. Java Basics - Anfänger-Themen 2
B Kommunikation mit Seriellen Schnittstellen + Integration einer lib Java Basics - Anfänger-Themen 1
A Daten aus einer HashMap aus einer DB speichern und mit neuen Werten vergleichen Java Basics - Anfänger-Themen 8
P Welches SDK für das erstellen einer ausführbaren Datei? Java Basics - Anfänger-Themen 4
D Länge einer Liste aufrufen. Java Basics - Anfänger-Themen 19
J Klassen Instanzen einer Klasse in einer anderen unabhängigen Klasse nutzen Java Basics - Anfänger-Themen 4
B Alle Strings bis zu einer Maimallänge aufzählen, die Bedingung erfüllen Java Basics - Anfänger-Themen 13
marcelnedza Finde meinen Fehler in einer Methode nicht, Java Karol Java Basics - Anfänger-Themen 15
Soranix Erste Schritte Struktur als Anfänger // Von einer Klasse auf ein Objekt einer anderen Klasse zugreifen. Java Basics - Anfänger-Themen 6
MoxMorris Wie macht man String[] = String[] aus einer anderer Methode? Java Basics - Anfänger-Themen 18
T Fibonacci mit einer Hilfsmethode berechnen Java Basics - Anfänger-Themen 10
S Hilfe zu einer Aufgabe Java Basics - Anfänger-Themen 5
M Radius von einer ellipse bestimmen Java Basics - Anfänger-Themen 7
Say Fehlenden Code finden in einer while-Schleife? Java Basics - Anfänger-Themen 11
M Zufallszahl generieren mit einer linken und rechten Grenze Java Basics - Anfänger-Themen 3
N Was Passiert mit dem Namen einer Variable, wenn man diese einer Liste Hinzufügt Java Basics - Anfänger-Themen 16

Ähnliche Java Themen

Neue Themen


Oben