# persistente, multi-threaded Verbindungen



## assoziatives pseudonym (7. Aug 2007)

Also, ich möchte mich zuallererst entschuldigen, und zwar für den Fall dass meine Antwort tatsächlich schon beantwortet wurde, in dem Fall bitte möglichst freundlich zur Lösung verweisen, danke.

Problemstellung:

Eine Java-Klasse soll auf einem Server als Daemon unbegrenzt lange laufen, auf eingehende Verbindungen warten, diese in Threads einteilen und somit alle gleichzeitig / entsprechend der Thread-Queue bedienen, bei keinen eingehenden Daten ein Keep-Alive-Signal erwarten und danach X ms schlafen gehen (Thread.currentThread.sleep() ?), beim nächsten Durchlauf wieder auf das Signal warten.

Der Daemon (ich nenne es einfach mal so, bezeichnet ab jetzt diese Klasse) soll auf keinen Fall die Sockets beenden, sondern einfach so lange offenhalten wie Keep-Alive-Signale eingehen

Bisher erreicht:

Daemon hört auf eingehende Verbindungen und wartet auf ein Keep-Alive-Signal, schläft dann und erwartet selbiges erneut, ABER: ich kann selbst mit Anleitungen von Universitäten nicht erreichen, dass mehrere Verbindungen bedient werden. Im Howto stand, es würde über diesen Weg möglich sein, alle clients zu bedienen und für jeden einen seperaten Thread zu eröffnen. Dem ist aber *nicht* so! Immer wenn ich Thread.currentThread.getId() ausgeben lasse, dann erscheint jedesmal die ID (oder der Name, auch bereits getestet) der *allerersten* Verbindung, neue Verbindungen werden auf der Clientseite anscheinend akzeptiert (keine Fehlermeldungen), aber auf der Serverseite passiert *nichts*. Bin ich einfach zu blöd, oder schafft es nedmal eine Uni, mehrere Verbindungen zu behandeln??

Ich bitte den Code-Wirrwar zu entschuldigen, aber ich versuche mit demselben Prinzip nun schon tagelang herum, der ursprüngliche Code sah viel einfacher und logischer aus

Server-Seite:

```
class client implements Runnable {
    private Vector handler = new Vector();
    private Vector threadsundsockets = new Vector();    
    private int id;
    private String nachricht;
    
    public client(Socket sock, int id) {
        this.handler.addElement(this.threadsundsockets);
        Vector beide = (Vector)this.handler.elementAt(id);
        beide.addElement(sock);
        beide.addElement(sock.toString());
        this.id = id;
  }
    
    
   
    
    public void run() {
        try {
            Vector beide = (Vector)this.handler.elementAt(this.id);
            Socket aktuellersocket = (Socket)beide.elementAt(0);
            Thread.currentThread().setName((String)beide.elementAt(1));
            aktuellersocket.setSoTimeout(5000);
            aktuellersocket.setKeepAlive(true);
            essentials meins = new essentials(aktuellersocket);
            //int i = 0;
            while(aktuellersocket.isClosed() == false) {
                //i++;
            
                
                if(meins.empfangen().equals("KEEPALIVE") == false) {
                   aktuellersocket.close(); }
                else {
                    System.out.println("Wir haben eine positive Antwort von Thread \""+Thread.currentThread().getName()+
                            "\" und legen uns jetzt schlafen...");
                    
                    Thread.currentThread().yield();
                     }
                    
            }
        } catch(Exception e) {e.printStackTrace(); }
        }
    public void stop() throws IOException {
        //this.socket.close();
        Thread.currentThread().interrupt();
    }
}


public class Server {
    
      
    
   public static void main(String args[]) {
    boolean benutzertreffer=false;

        try {
         
         ServerSocket ssocket = new ServerSocket(60000);         
         
       
        int i = 0;
         while(true) {
            
             Socket socket = ssocket.accept();
             ssocket.setReuseAddress(false);
             
             if(socket.isConnected()) {
                 client meiner = new client(socket, i);
                 meiner.run();
                 continue;
             } else {
                 System.out.println("Socket ist nicht konnektiert, daemon wird also nicht gestartet!");
             }
             i++;
             
              
        }
         
    
     }
      catch(Exception e) {e.printStackTrace();
      }
   }
```
Client-Seite:

```
this.socket = new Socket("localhost", 60000);
                                this.socket.setSoTimeout(5000);
                                this.socket.setKeepAlive(true);
                                essentials meins2 = new essentials(this.socket);
                                while(true) {
                                    meins2.senden("KEEPALIVE");
                                    Thread.currentThread().yield();
                                }
```

Die Klasse "essentials" ist nichts weiter als InputStream.read() und OutputStream.write() innerhalb von schleifen, so wird zb. bei  InputStream.read() solange ein byte eingelesen, bis die letzten 4 bytes gecastet ein "STOP" ergeben ... nicht weltbewegendes.[/code]

Die seltsame Handhabung der Threads mittels Vektoren usw. tut nichts zur Sache, das stellt nur meinen letzten Versuch dar, das Ergebnis war das gleiche:

1. eingehende Verbindung klappt wunderbar, 2. klappt auf der Client-Seite anscheinend auch, aber am Server tut sich nichts.


----------



## assoziatives pseudonym (7. Aug 2007)

weiß niemand ne antwort??


----------



## Gast (7. Aug 2007)

Hallo,

soll ich ehrlich sein  
Bei Aussagen wie 





			
				tha_specializt hat gesagt.:
			
		

> ...schafft es nedmal eine Uni,..


 Was soll man dazu noch sagen, da kann man doch nur verlieren!

Das muss mal  ein specializt ran.

Grüzzi


----------



## assoziatives pseudonym (7. Aug 2007)

naja, erstens hat der kleine Junge über mir nedmal den Unterschied zwischen einer Frage und einer Aussage verstanden, zweitens lässt sich der Bub von Namen beeinflussen und drittens hab ich mittlerweile die Lösung:

Meine Vorlage der Uni war  / ist tatsächlich fehlerhaft, denn es wird 
	
	
	
	





```
implements Runnable
```
 benutzt. Runnable selbst garantiert aber nur einen thread*sicheren* Ablauf, stellt aber einen solchen nicht wirklich dar (benutzt nur ähnliche Techniken, so weit ich weiss)
Man kriegt mein Beispiel also ganz leicht zum laufen (und damit auch das beispiel der Uni), indem man auf 
	
	
	
	





```
extends Thread
```
 setzt.

Soviel dazu, ich hoffe dass nun auch der Jugendliche über mir ein wenig schlauer ist, und fortan nicht mehr *ganz* so lächerlichen Schwachsinn brabbelt. Viel Glück, kleiner
Kleinen Tip kriegste noch mit auf deinen langen, langen Weg: 





> Aufklärung ist der Ausgang des Menschen aus seiner selbst verschuldeten Unmündigkeit


 ergo: Nur weil viele / einige Menschen dasselbe sagen, muss es noch lange nicht richtig sein, lerne selbst zu denken und hilf mit Fehler zu bereinigen!


----------



## HoaX (7. Aug 2007)

nein, und runnable macht garnichts thread*sicher*, darum musst du dich mit synchronized und locks selber kümmern. es bietet nur die möglichkeit code von einem thread ausführen zu lassen ohne eine neue klasse von thread abzuleiten. würdest du im ursprungscode statt 
	
	
	
	





```
meiner.run()
```
 einfach 
	
	
	
	





```
new Thread(meiner).start()
```
 schreiben würde es funktionieren.


----------



## assoziatives pseudonym (8. Aug 2007)

ah, sehr gut. Danke!
Das mit synchronized & co werd ich mir jetzt auch mal angucken, weil genau solchen Sachen bei dieser Anwendung nämlich wichtig sind, und ich aus bestimmten Gründen gerne auf "extends" verzichten würde. Vielen Dank nochmal.


----------



## tuxedo (8. Aug 2007)

Erst die Klappe groß aufreißen und andere "kleinen Bub" und "schwachsinn brabblende Jugendliche" nennen, und dann wieder "kuschen" ...
Naja, wir lernen alle noch dazu ;-)


----------



## assoziatives pseudonym (8. Aug 2007)

Ah, wie ich sehe werd ich grad zugetrollt ... die Herren glauben mich zu kennen (sind wohl Götter) und urteilen schnell ... so wie es Kinder gerne machen. Naja, viel Spass noch


----------



## jPat (8. Aug 2007)

:bloed:


----------



## assoziatives pseudonym (8. Aug 2007)

jPat hat gesagt.:
			
		

> :bloed:


 :toll:


----------



## jPat (8. Aug 2007)

:bloed:  :bae:


----------



## tuxedo (8. Aug 2007)

*Kopfschüttel* Oh Herr, wo soll das noch hinführen ?


----------



## assoziatives pseudonym (8. Aug 2007)




----------

