# TCP-Server soll viele offene Verbindungen verwalten



## elinmerl (21. Jan 2009)

Hallo allerseits!

Ich muss ein Programm entwickeln, welches viele (größer 1000) *geöffnete* Verbindungen verwalten kann.

Grundsätzlicher Aufbau wäre also:
Server wartet mit accept() auf eingehende Verbindungen.
Wird eine Verbindung aufgebaut, wird diese in eine Collection einsortiert und bleibt geöffnet.
Dann wartet der Server wieder auf eine neue Verbindung.

Die erste Frage die ich mir stelle, wie viele Verbindungen kann ich annehmen und offen halten?

Und das zweite Problem: Wie verwalte ich diese Verbindungen. Ich denke ja mal nicht, dass ich für jede Verbindung einen Thread öffnen kann. Falls doch, wäre mein Problem prinzipiell gelöst. 
Wenn ich also keine Threads für jede Verbindung öffnen kann, muss ich die Verbindungen regelmäßig pollen um zu sehen ob Daten angekommen sind. Nur pollen bedeutet, dass ich CPU-Zeit vergeude.  

Hat jemand eine andere Idee?

Andreas


----------



## Ebenius (21. Jan 2009)

Ich bin für einen Thread pro Port.


----------



## elinmerl (21. Jan 2009)

Ebenius hat gesagt.:
			
		

> Ich bin für einen Thread pro Port.



Und Du meinst, dass ich mehr als 1000 Threads anlegen kann?

Andreas


----------



## Ebenius (21. Jan 2009)

Probier's doch einfach aus. Zum Beispiel so: 
	
	
	
	





```
/**
 * Test main method.
 * 
 * @param args ignored
 * @throws InterruptedException
 */
public static void main(String[] args) throws InterruptedException {
  final Runnable connectionHandlerFake = new Runnable() {

    @Override
    public synchronized void run() {
      try {
        wait();
      } catch (InterruptedException ex) {
        // interrupted
        return;
      }
    }
  };

  final Thread[] threads = new Thread[2000];
  final NumberFormat nf = new DecimalFormat("0000");
  final DateFormat df = new SimpleDateFormat("HH:mm:ss,SSS");

  System.out.println(df.format(new Date())
        + " [main thread] Creating and starting "
        + threads.length
        + " threads ...");
  for (int i = 0; i < threads.length; i++) {
    final Thread thread = new Thread(connectionHandlerFake);
    thread.setDaemon(true);
    thread.setName("Connection Handler " + nf.format(i));
    thread.start();
    threads[i] = thread;
  }
  System.out.println(df.format(new Date())
        + " [main thread] All threads created");

  new Thread(new Runnable() {

    @Override
    public void run() {
      try {
        System.out.println(df.format(new Date())
              + " [notifier thread] "
              + "Waiting for 10 seconds prior to notifyAll ...");
        Thread.sleep(10 * 1000);
        System.out.println(df.format(new Date())
              + " [notifier thread] Notifying all threads ...");
        synchronized (connectionHandlerFake) {
          connectionHandlerFake.notifyAll();
        }
        System.out.println(df.format(new Date())
              + " [notifier thread] All threads notified");
      } catch (InterruptedException ex) {
        ex.printStackTrace();
      }
    }
  }).start();

  System.out.println(df.format(new Date())
        + " [main thread] Joining all children");
  for (int i = 0; i < threads.length; i++) {
    threads[i].join();
  }
  System.out.println(df.format(new Date())
        + " [main thread] All children joined");
}
```



			
				Mein Programm hat gesagt.:
			
		

> 14:50:29,039 [main thread] Creating and starting 2000 threads ...
> 14:50:29,510 [main thread] All threads created
> 14:50:29,511 [main thread] Joining all children
> 14:50:29,511 [notifier thread] Waiting for 10 seconds prior to notifyAll ...
> ...



Ebenius


----------



## tuxedo (21. Jan 2009)

1000 Threads? Das ist dann ja nicht mehr wirklich performant mit Java IO.

Würde Java NIO verwenden. Da braucht man nicht für jeden Client einen Thread. Oder noch besser gleich soetwas wie Apache MINA benutzen...

Bei allem anderen "dispatcht" sich der Threaddispatcher zu tode ...

- Alex


----------



## Ebenius (21. Jan 2009)

tuxedo hat gesagt.:
			
		

> Bei allem anderen "dispatcht" sich der Threaddispatcher zu tode ...



Das hängt doch nur davon ab, wie oft die Threads aktiviert werden. Normaler weise werden die meisten Threads in einem wait hängen, bis mal Daten über den Strom huschen. Damit kann man eigentlich gut leben.

Aber wenn man mit NIO oder MINA sowas besser lösen kann. Gern. Hab ich normaler Weise nicht so viel (NIO) bzw. nichts (MINA) zu tun.

Ebenius


----------



## tuxedo (21. Jan 2009)

Ich weiß ja nicht was der Server zu machen/bearbeiten hat. Aber ich tippe mal darauf dass eine 0815 Serveranwendung die Clients bedienen muss, bei >=1000 Clients schon im Schnitt einige hundert Clients irgendwie aktiv sind. 

Zumindest würde ich nicht das "Risiko" eingehen wollen. Klar, die Chefs/Produktmanager meinen am Anfang oft "nur was kleines, wird nix großes". BIs sie sehen dass sich's gut verkauft und dann doch "was großes" wird. Und dann passt die Architektur vorne und hinten nicht.

Die Einarbeitungszeit in MINA ist nicht allzu hoch wenn man sich die Samples anschaut. Und man hat noch den Vorteil dass man gleich bequem und sehr abstrakt entwicklen kann statt sich um alles Grundlegende selbst zu kümmern.

gut, muss nicht MINA sein. Jedem das seine. Aber zumindest anschauen würd' ich's mal bevor ich anfange mit "normalem" IO einen Server für >=1000 Clients zu entwickeln.

- Alex


----------



## elinmerl (22. Jan 2009)

Hallo,

danke erst einmal für eure Antworten.

Meine Entscheidung fällt auf NIO. Mina schaue ich mir auch noch an. 
Für "reines" NIO habe ich folgendes gefunden:

http://www.onjava.com/pub/a/onjava/2004/09/01/nio.html

Nur falls mal noch jemand so ein Problem hat. 

Andreas


----------



## tuxedo (22. Jan 2009)

Naja, nacktes NIO ist nicht einfach zu verwenden. Hab selbst einge Wochen gebraucht bis ich ein stabiles und brauchbares Grundgerüst hatte.
Bin dann aber doch zu MINA gewechselt weil's einfach genial zu verwenden ist und prima erweitert und für die eigenen bedürfnisse zurechtgeschnitten werden kann.

- Alex


----------



## Robert Haag (22. Jan 2009)

neben MINA gibt es auch xSocket. Ich finde das einfacher


----------



## tuxedo (23. Jan 2009)

Jepp. xSocket abstrahiert einfach nur NIO. MINA geht da einen Schritt weiter und bietet schon Features für Protokolle und unterschiedliche "Transports".

- Alex


----------



## elinmerl (23. Jan 2009)

Hallo,

nachdem ich mich einen Tag mit NIO beschäftigt habe, habe ich mir doch noch MINA angeschaut. UNd ich muss sagen: Zum Glück! Im Vergleich zu reinem NIO ist MINA recht einfach zu verstehen und anzuwenden.
Danke noch einmal für diesen Hinweis!

Andreas


----------



## tuxedo (24. Jan 2009)

Sag ich doch.

xSocket ist aber auch okay wenn man sehr low-level auf der NIO-Schicht arbeiten will.

Parallel zu MINA gibts noch NETTY. Kann man sich auch mal anschauen. Sind aber seeeehr verwand (haben den gleichen Ursprung).

- Alex


----------

