# Nachricht über Sockets kommt nicht an



## Big Al (24. Sep 2008)

Hi,
ich habe gerade angefangen, mich mit Java zu beschäftigen. Da ich von C# komme, wollte ich mal einen alten Netzwerkchat nach Java übertragen. Nur Kommt aus einem mir leider nicht ersichtlichen Grund die Nachricht am Ende des Streams nicht raus. Am besten ich poste mal meinen Code.
Das hier ist der Code, der im Server in einem Thread den Stream liest:
(Client ist der Socket, outStack der Stack mit den Nachrichten, die raus sollen)


```
java.io.InputStream in;
            java.io.OutputStream out;
            java.io.BufferedReader reader;
            java.io.BufferedWriter writer;

            in = Client.getInputStream();
            out = Client.getOutputStream();
            writer = new BufferedWriter(new java.io.OutputStreamWriter(out));
            reader = new java.io.BufferedReader(new java.io.InputStreamReader(in));

            while (!stopRequested) {
                while (in.available() > 0)
                {
                    observer.HandleInputMessage(reader.readLine());
                }
            while (!outStack.empty()) {
                    writer.write(outStack.pop());

                try {
                    java.lang.Thread.sleep(100);
                } catch (InterruptedException ex) {
                    Logger.getLogger(RemoteClientHandler.class.getName()).log(Level.SEVERE, null, ex);
                }

                }
            }
            in.close();
            out.close();
```

Hier zeigt in.available() leider immer das Ergebnis 0.
Hier der Code, der im Client läuft:

```
java.io.BufferedReader reader = null;
            java.io.BufferedWriter writer = null;
            try {
                reader = new java.io.BufferedReader(new java.io.InputStreamReader(Client.getInputStream()));
                writer = new java.io.BufferedWriter(new java.io.OutputStreamWriter(Client.getOutputStream()));
                
                while(!stopRequested)
                {
                    while(reader.ready())
                    {
                        String msg = reader.readLine();
                        if(observer != null)
                            observer.HandleInputMessage(msg);
                    }
                    while(!outStack.empty())
                    {
                        writer.write(outStack.pop());
                    }
                    try {
                        java.lang.Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                
            } catch (IOException ex) {
                Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    reader.close();
                    writer.close();
                } catch (IOException ex) {
                    Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
```
Wenn ich debugge und einen Breakpoint auf writer.write(outStack.pop()); setze wird der auch ausgelöst, die Nachricht müsste also rausgehen.
Wäre schön wenn mich jemand aufklären würde, was man da in Java anders machen muss.
Vielen Dank,
Alexander


----------



## FArt (24. Sep 2008)

Könnte sein, dass der Puffer deines BufferedWriters noch nicht voll genug ist und sich der Writer noch nicht bemüßigt fühlt, die Daten auch wirklich zu verschicken...
Versuche es mal ungepuffert oder mit einem flush().


----------



## Big Al (24. Sep 2008)

Hi,
das hätte wirklich sein können, denn ich versende zum testen grade nur ein "Hello World". Aber leider bringen beide Vorschläge nicht das gewünschte Ergebnis. Trotzdem vielen Dank für den Vorschlag!
Alexander


----------



## tuxedo (24. Sep 2008)

Hast du mal versucht den Buffer* wegzulassen? Der machts in deinem Fall nicht unbedingt einfacher oder schneller...


btw:


```
catch (InterruptedException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }
```

Das ist irgendwie stumpfsinnig. In der Regel holt man sich den Logger gleich als Instanzvariable und benutzt ihn dann Klassenweit. Aber den in jeder Exception anzulegen .... ich weiß nicht.

Gruß
Alex


----------



## SlaterB (24. Sep 2008)

schreibe statt in den Socket zunächst einmal in einem StringWriter/ ByteArrayOutputStream und schaue dir im Programm an, was dort herauskommt

oder auch per FileWriter in eine Datei,

-------

außerdem solltest du bedenken, dass 
reader.readLine();
erst dann was lesen kann, wenn die Gegenseite auch einen Zeilenumbruch schickt,
aber da available() 0 ist, dürfte das Problem woanders sein


----------



## Guest (24. Sep 2008)

> außerdem solltest du bedenken, dass
> reader.readLine();
> erst dann was lesen kann, wenn die Gegenseite auch einen Zeilenumbruch schickt,
> aber da available() 0 ist, dürfte das Problem woanders sein


Guter Punkt, das muss auf jeden Fall geändert werden. Der Vorschlag mit dem File ist auch gut, werde ich gleich mal ausprobieren.
Zu der Exception:
Also das find ich ja an Java ein bisschen komisch, dass man jede eventuelle Exception abfangen muss. Obwohl es ja eigentlich Sinn macht. Das try - catch hat NetBeans erstellt, da hab ichs einfach so gelassen.
Meinst du, dass der Logger in ein Singleton sollte?
Naja, mein Hauptaugenmerk liegt erst mal darauf, das Ding zum Senden und Empfangen zu bringen, dann wende ich mich den Schönheitsfehlern zu. Ist sozusagen mein Startprojekt für Java, das mich mal ein bisschen motivieren soll. Dafür muss das Ganze erst funktionieren.
Vielen Dank für die guten Vorschläge, werde ich alles gleich ausprobieren.
Grüße,
Alexander


----------



## Wildcard (24. Sep 2008)

tuxedo hat gesagt.:
			
		

> Das ist irgendwie stumpfsinnig. In der Regel holt man sich den Logger gleich als Instanzvariable und benutzt ihn dann Klassenweit. Aber den in jeder Exception anzulegen .... ich weiß nicht.


API-Doc lesen  :wink: 
http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Logger.html#getLogger(java.lang.String)


----------



## Big Al (25. Sep 2008)

Hi,
ich habe jetzt mal den Output des Clients in ein File schreiben lassen und dort kommt auch alles super an. Das seltsame ist, dass die accept()-Methode ja den Client annimt und eine Verbindung herstellt. Dass der Stream an eine falsche Adresse geht ist damit ja ausgeschlossen.
Ich bin leider nach wie vor ziemlich ratlos.
Alexander


----------



## tuxedo (25. Sep 2008)

Wildcard hat gesagt.:
			
		

> tuxedo hat gesagt.:
> 
> 
> 
> ...



Ja, sorry, die APIDOC hab ich schon (fast) vor Jahren zu dem Thema konsultiert. Anlegen ist etwas falsch ausgedrückt. "Holen" im wäre geschickter gewesen. Dennoch macht dieses Vorgehen den Code nicht besonders übersichtlich/leserlich.

- Alex


----------

