001: // You can redistribute this software and/or modify it under the terms of
002: // the Ozone Library License version 1 published by ozone-db.org.
003: //
004: // The original code and portions created by SMB are
005: // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006: //
007: // $Id: DxMultiServer.java,v 1.1 2001/12/18 10:31:30 per_nyfelt Exp $
008:
009: package org.ozoneDB.DxLib.net;
010:
011: import java.io.*;
012: import java.net.*;
013: import org.ozoneDB.DxLib.*;
014:
015: /**
016: * DxMultiServer verwaltet mehrere DxClients - Verbindungen. Durch einen Thread
017: * wird staendig auf neue Verbindungen gewartet, durch einen weiteren auf
018: * einkommende Daten. Wird etwas empfangen, wird die Methode handleClientEvent()
019: * aufgerufen.
020: *
021: *
022: * @author <a href="http://www.softwarebuero.de/">SMB</a>
023: * @version $Revision: 1.1 $Date: 2001/12/18 10:31:30 $
024: */
025: public abstract class DxMultiServer extends DxListBag {
026:
027: protected ServerSocket serverSocket;
028:
029: protected Acceptor acceptor;
030:
031: protected Thread acceptThread;
032:
033: protected ThreadGroup threadGroup;
034:
035: public DxMultiServer(int port) throws IOException {
036: serverSocket = new ServerSocket(port);
037: acceptor = new Acceptor(this );
038: threadGroup = new ThreadGroup(getClass().getName());
039: acceptThread = newThread(acceptor);
040: }
041:
042: /**
043: * liefert die ThreadGroup des MultiServers.
044: */
045: public ThreadGroup threadGroup() {
046: return threadGroup;
047: }
048:
049: /**
050: * Diese Methode liefert einen neuen Thread und wird fuer die AcceptThread
051: * und den DxMultiServerClient benoetigt. Sie kann ueberschrieben werden, um evtl.
052: * eigene Threads zu erzeugen (z.B. bei Verwendung eines eigenen Schedulers).
053: * Ausserdem wird der mit diesem Thread verbundene Client uebergeben (kann
054: * auch null sein !!).
055: */
056: public Thread newThread(Runnable run) {
057: return new Thread(threadGroup(), run);
058: }
059:
060: /**
061: * erzeugt einen neuen client aus einer socket-verbindung;
062: * diese methode kann ueberschrieben werden, um evtl. eigene clients
063: * einfuegen zu koennen
064: */
065: public synchronized DxMultiServerClient newClient(Socket sock) {
066: try {
067: return new DxMultiServerClient(sock, this );
068: } catch (Exception e) {
069: return null;
070: }
071: }
072:
073: /** accept thread starten */
074: public void accept() {
075: if (!acceptThread.isAlive()) {
076: acceptThread.start();
077: }
078: }
079:
080: public void close() throws IOException {
081: acceptThread.stop();
082: DxIterator it = iterator();
083: while (it.next() != null) {
084: ((DxMultiServerClient) it.object()).close();
085: }
086: serverSocket.close();
087: }
088:
089: public synchronized void removeClient(DxMultiServerClient client) {
090: DxIterator it = iterator();
091: DxMultiServerClient cl;
092: while ((cl = (DxMultiServerClient) it.next()) != null) {
093: if (cl == client) {
094: it.removeObject();
095: cl.close();
096: return;
097: }
098: }
099: throw new RuntimeException("removeClient(): no such client.");
100: }
101:
102: /**
103: * diese methode wird aufgerufen, wenn an der verbindung client daten
104: * anliegen; muss ueberschrieben werden, um das applications spezifische
105: * verhalten zu bestimmen
106: */
107: public abstract void handleClientEvent(DxMultiServerClient client,
108: Object event);
109:
110: public abstract void handleClientException(
111: DxMultiServerClient client, Exception e);
112: }
|