# Outputstream von anderem Thread verwenden lassen



## PAX (21. Nov 2008)

Hallo Freunde.

Ich finde zu meinem Problem keine Lösung. Aber vielleicht habt ihr damit bereits Erfahrung gemacht.

Ich versuche mit den Klassen, Socket und ServerSocket, ein einfaches Anfrage-/Antwortszenario zu realisieren. Sofern beide Programme (Server und Client) direkt miteinander kommunizieren, klappt das auch. Doch sobald ich den Server bei jeder Anfrage einen neuen Thread erzeugen lasse, der dann in den Outputstream schreiben soll, scheint er unendlich lange zu schreiben, bzw. nie zum Ende zu kommen. Ich habe zum einen probiert, lediglich eine Referenz auf das BufferedOutputStream-Objekt an den neuen Thread zu übergeben und zum anderen versuchte ich es damit, die Referenz des von der accept-Methode zurückgelieferten Socket-Objektes dem neuen Thread zu geben. Beides leider nachwievor erfolglos. Bei zweiterer Variante funktioniert noch nicht einmal das einlesen der Anfrage-Bytes.

Server erzeugen nunmal für jede Anfrage einen seperaten Thread. Doch wie soll ich das realisieren, wenn dann die Streams nicht mehr funktionieren?

Hier der (vereinfachte) Clientcode zur ungefähren Illustration:

```
Socket server = null;
            try
            {
                        server = new Socket("paxnotebook", 23235);
                        BufferedInputStream in = new BufferedInputStream(server.getInputStream());
                        BufferedOutputStream out = new BufferedOutputStream(server.getOutputStream());
                        
                        out.write(86);
                        out.flush();
                        System.out.println("Antwort: "+in.read());
...
```

Hier der Server (vereinfacht):

```
Socket client = null;
        ServerSocket serverSocket = new ServerSocket(23235);
...
        while (true)
        {
                client = serverSocket.accept();

                if (client != null)
                {
                    new Test(client);
                    client = null;
                }
        }
...
```

Der neu erzeugte Thread:

```
private Socket client;

    public Test(Socket client)
    {
        this.client = client;
        //this.setDaemon(true);
        this.start();
    }

    @Override
    public void run()
    {
        try
        {
            System.out.println("Anfrage wird verarbeitet...");
            BufferedInputStream in = new BufferedInputStream(client.getInputStream());
            BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
            StringBuffer inpStream = new StringBuffer();
            for (int b = in.read(); b != -1; b = in.read())
                inpStream.append((char) b);

            System.out.println("Anfrage erhalten: " + inpStream);
            out.write(23);
            out.flush();
...
```


Nun bin ich gespannt. 

Beste Grüße


PAX


----------



## Murray (21. Nov 2008)

javadoc hat gesagt.:
			
		

> java.io.InputStream.read
> 
> public abstract int read()
> throws IOException
> ...



Warum also sollte dieser Code 
	
	
	
	





```
for (int b = in.read(); b != -1; b = in.read())
```
 jemals terminieren?


----------



## PAX (21. Nov 2008)

weil b irgendwann der wert -1 zugewiesen wird (sobald keine daten mehr kommen) und dann die schleifenbedingung nicht mehr erfüllt ist.


----------



## PAX (21. Nov 2008)

ähm... ich bin gerade "etwas" verwirrt... lasse ich das einlesen der daten vom client ganz sein, komme ich auch beim code mit dem senden der antwort an, die der client dann auch erhält...

ich kann aber wirklich nicht nachvollziehen, warum das einlesen der anfragebytes vom client nicht funktioniert? ersetze ich das for-konstrukt durch folgende alternative:


```
int b;
            do
            {
                b = in.read();
                if (b != -1) inpStream.append((char) b);
            }while(b != -1);
            //for (int b = in.read(); b != -1; b = in.read())
```

funktionierts ebenfalls nicht.

was ist denn blos los? hab ich einen knick im gehirn?  

beste grüße


PAX


NACHTRAG:
ich hab innerhalb der schleife einmal ausgeben lassen, was b denn so erhält. und mit verwunderung stelle ich fest, dass es immer genau das bekommt, was der client auch an den server an bytes gesendet hat. allerdings scheint die schleife am ende der zu übertragenden bytes dann offensichtlich einzufrieren.
das kann ich, ehrlich gesagt, nicht verstehen. denn müsste nicht zum schluss -1 zurückgeliefert werden? das beendet doch die schleife?


----------



## Murray (21. Nov 2008)

PAX hat gesagt.:
			
		

> weil b irgendwann der wert -1 zugewiesen wird *(sobald keine daten mehr kommen)* und dann die schleifenbedingung nicht mehr erfüllt ist.


Genau das ist der Punkt: der Stream kann ja nicht riechen, dass keine Daten mehr kommen - wann sollte er denn abbrechen? Nach 10 Millisekunden? Nach 100 Millisekunden? Oder erst nach 5 Minuten?
Bei einen FileInputStream oder einen ByteArrayInputStream ist das anders; dort kann der InputStream wissen, wann nichts mehr kommen kann; bei diesen Streams wird read dann auch irgendwann -1 liefern. Bei einem SocketInputStream geht das nicht, denn die empfangende Seite kann ja nicht wissen, ob der Sender nicht im nächsten Moment noch etwas schicken wird.


----------



## PAX (21. Nov 2008)

darauf wäre ich (wenn überhaupt) lange nicht gekommen.  

ich danke dir, Murray!

beste grüße


PAX


----------

