# flush() bewirkt nichts ?



## Guest (28. Nov 2007)

Hi,

ich habe ein kleines Server/Client Testsystem geschrieben. Das Senden klappt nur dann wenn ich auf der Senderseite mit meinem PrintWriter ein close() mache. Dabei schließt es dann natürlich auch den Socket ich nicht gebrauchen kann.flush() bringt leider nichts.


Server

```
out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

out.print("TEST");
out.flush(); // stattdessen hier ein out.close() und ich empfange die Nachricht... ?
```

Client

```
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

message ="";
BUFFERSIZE = 1024; // habe ich auch schon mit 1 probiert...

while ( (len = in.read(buf, 0, BUFFERSIZE)) != -1)  	
   message += new String(buf,0,BUFFERSIZE);
				
System.out.println(message);
```


Kann mir irgendwer sagen wieso das nicht klappt? Ich finds einfach nicht raus.


----------



## tuxedo (28. Nov 2007)

Probiers mal ohne bufferedreader ... also direkt mit input und outputstream ... Dann sollte es gehen. PrintWriter ist auch nicht das wahre. Probier da mal einen DataOutputStream und auf der anderen Seite einen DataInputStream.

- Alex


----------



## Guest (28. Nov 2007)

haut auch nicht hin :-/

auch hier das selbe problem. mit close() gehts, mit flush() nicht...


----------



## Guest (28. Nov 2007)

Hier nochmal der komplette Code. Ich versteh es einfach nicht. Ist doch eigentlich simpel und überschaubar. Das Forum habe ich abgegrast und mich berets dummgegoogelt. Bitte helft mir. Oder kann man den Socket am Ende garnicht offen lassen?


SERVER

```
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class TestSrv {

	public static void main(String[] args)
	{
		int port = 1234;
		
		try
		{
				ServerSocket srvsocket = new ServerSocket(port);
				Socket client_socket;
				DataOutputStream out;
			
				while(true)
				{
					client_socket = srvsocket.accept();	
					out= new DataOutputStream(client_socket.getOutputStream());
						
					out.writeBytes("abcdef123456");
					out.flush(); // damn mf****in  flush..... mit close() gehts auch hier...
				}
		}
		catch(Exception e)
		{			
		}
	}
}
```

CLIENT

```
import java.io.DataInputStream;
import java.net.Socket;

public class TestCl {

	public static void main(String[] args) {

		String hostip = "127.0.0.1";
		int    port	  = 1234;
		
		try
		{
			Socket server_socket = new Socket(hostip,port);			
			DataInputStream  in 	= new DataInputStream(server_socket.getInputStream());

			
			String message="";
			byte[] b = new byte[8];
			
	        while ( (in.read(b, 0, 8)) != -1)  	
	        	message += new String(b,0,8);			
			
			System.out.println(message);
			
			server_socket.close();
		}
		catch(Exception e)
		{
			
		}
	}
}
```


Ich kann den socket leider nicht einfach so schliessen weil ich gerne noch was zurücksenden würde... close() fällt einfach total aus (und ist sicherlich auch nicht im Sinne des Erfinders...). PLZ HELP!


----------



## DocRandom (28. Nov 2007)

Hi!

Wenn Du mit 
	
	
	
	





```
void writeBytes(String s)
```
 arbeitest, solltest Du zum lesen auch die richtigen Methoden verwenden:

```
void readFully(Byte[] b)
void readFully(Byte[] b, int off, int len)
```

lg
DocRandom


----------



## SlaterB (28. Nov 2007)

dein Client liest die Daten schon recht zügig,
aber ihm reichen die ankommenden Daten nicht, du hast eine while-Schleife, die immer weiter liest,

verwende mal


```
public class Test
{

    public static void main(String[] args)
        throws Exception
    {
        Socket socket = new Socket("localhost", 1234);
        System.out.println("socket da");
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String message = "";
        int BUFFERSIZE = 1024;
        int len = 0;
        char[] buf = new char[BUFFERSIZE];
        while ((len = in.read(buf, 0, BUFFERSIZE)) != -1)
        {
            message += new String(buf, 0, len);
            System.out.println("message so far: " + message);
        }

        System.out.println("end: " + message);

    }
}
```


----------



## Guest (29. Nov 2007)

@Slater: Funktioniert leider auch nicht. Die Schleife wartet auf die "-1", und die kommt einfach nicht wenn ich flush() verwende...  :autsch:

der Output deines Clients:


> socket da
> message so far: abcdef123456




@DocRandom: Leider hat readFully keinen Rückgabetyp. Ich kann also nicht erkennen wann das Ende des Streams erreiocht ist, es sei denn ich würde ein extra Zeichen am Ende des Streams dafür verwenden(Fällt auch aus, davon wissen andere Implementierungen nichts...). Davon mal abgesehen hat readFully() nur dann funktioniert wenn ich immer genau ein Byte gelesen habe....


WARUM NUR???  :bahnhof:


----------



## SlaterB (29. Nov 2007)

die -1 kommt erst, wenn der Stream geschlossen wird, so ist das gewollt?!..


----------



## Guest (29. Nov 2007)

Wenn der Stream geschlossen wird, wird aber auch der ganze Socket geschlossen. Ich will über den Socket aber nachdem ich was gelesen habe etwas zurückschicken  :-/

Und zu was soll dann flush() gut sein???


----------



## SlaterB (29. Nov 2007)

ohne flush würde vielleicht gar nix ankommen (oder doch, du hattest durch deine Schleife ja nix bemerkt),
mit flush bekommst du auf jeden Fall die Daten so schnell wie möglich und damit die 'message so far'-Ausgabe

wenn du den Stream nicht schließen willst, dann tue es nicht, schreibt dir doch niemand vor,
aber die Schleife wird dann ewig warten,
du hast von Server-Seite aus keine Möglichkeit -1 zu senden, um die Schleife zu beenden,

hier kommen *Protokolle* ins Spiel,
sende auf Serverseite den String "Ende dieser Teilnachricht",
auf Client-Seite liest du die Eingabe, und suchst nach "Ende dieser Teilnachricht" um die Schleife vorerst zu verlassen

(oder eine beliebige andere Absprache)


----------



## tuxedo (29. Nov 2007)

flush dient zum Ausgabepuffer leeren. Aber das steht auch in der API-Doku ...

- Alex


----------



## Guest (29. Nov 2007)

Wisst Ihr was seltsam ist? Mit readUTF() ist das alles kein Problem. Leider ist das irgendwie ein modifiziertes UTF-8, ich kanns also auch nicht verwenden.


----------



## schalentier (29. Nov 2007)

Du arbeitest mit Streams. Ein flush() bei einem BufferedWriter bewirkt, dass saemtliche Daten - die noch nicht gesendet wurden, sondern nur gebuffert sind - gesendet werden. 

read() liest Daten vom Stream und liefert die Anzahl gelesener Bytes zurueck. -1 falls der Stream geschlossen wurde. readFully() liest im Gegensatz zu read(), solange bis der uebergebene Buffer voll ist. Hier wird also gewartet, wenn keine Daten mehr ankommen, bis wieder welche ankommen. 

Was dir fehlt ist die Angabe der Anzahl der zu lesenden Bytes auf der Client-Seite. Die musst du (z.B. am Anfang) uebertragen, und kannst so readFully() verwenden. Oder du sendest ein Endesymbol (z.B 0x00) und musst dann read() nehmen und jedes empfangene Byte ueberpruefen (bzw nimm BufferedReader.readLine(), das liest bis ein '\n' gelesen wurde). 

Noch besser ist der angesprochene DataOutputStream. Damit kannst du primitive Datentypen direkt verschicken.


----------



## Guest (29. Nov 2007)

Okay, danke für Eure Antworten.

Jedes gelesene Zeichen zu überprüfen bis ein Terminierungssymbol kommt ist glaub ich sehr langsam. Also lieber zuerst die Länge vorab schicken, das hört sich besser an.


Kurz zum Hintergrund des Ganzen:

Es sollen Steuerdaten in XML versendet werden. Dabei ist es ganz besonders wichtig das alles nach gängigen Standards und Normen läuft. Leider empfange ich die Daten von einem in MS VisualBasic geschriebenen System, in Zukunft von den verschiedensten Plattformen. Die müssen die Daten auf jeden Fall in UTF-8 codiert schicken. Nur wie kann ich das mit meinem Server überprüfen? Generell sollen XML Anfragen die nicht UTF-8 entsprechen zurückgewiesen bzw. verworfen werden. Deshalb wollte ich also byteweise empfangen und das dann decodieren. Richtiger Ansatz?


----------

