summaryrefslogtreecommitdiff
path: root/source/com/c2kernel/utils/server/SimpleTCPIPServer.java
blob: 12e8ec4f6ec56d9fb7e18300129c24b1d62f2b94 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package com.c2kernel.utils.server;

import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.NoSuchElementException;

import com.c2kernel.utils.Logger;


public class SimpleTCPIPServer implements Runnable
{
    int                 port            = 0;
    int                 maxConn         = 10;
    Thread              listener        = null;
    Class               handlerClass    = null;
    ServerSocket        serverSocket    = null;
    boolean            keepListening   = true;
    ArrayList           currentHandlers = new ArrayList();
    static short       noServers = 0;

    public SimpleTCPIPServer(int port, Class handlerClass, int maxConnections)
    {
        this.port         = port;
        this.handlerClass = handlerClass;
        this.maxConn      = maxConnections;
        noServers++;
    }

    public void startListening()
    {
        if(listener != null) return;
        keepListening = true;
        
        listener = new Thread(this);
        listener.start();
    }
    
    public void stopListening()
    {
        Logger.msg("SimpleTCPIPServer: Closing server for " + handlerClass.getName() +" on port "+ port);
        keepListening = false;
        for (Iterator iter = currentHandlers.iterator(); iter.hasNext();) {
            SocketHandler thisHandler = (SocketHandler)iter.next();
            thisHandler.shutdown();
        }
    }

    public void run()
    {
        Thread.currentThread().setName("TCP/IP Server for "+handlerClass.getName());
        Socket       connectionSocket = null;
        InputStream  inputStream      = null;

        try {
            serverSocket = new ServerSocket(port);
            if (port == 0)
                port = serverSocket.getLocalPort();
            Logger.msg("SimpleTCPIPServer: Created server for " + handlerClass.getName()+" on port "+port);
            serverSocket.setSoTimeout(500);
            SocketHandler freeHandler = null;
            while(keepListening) {
                if (freeHandler == null || freeHandler.isBusy()) {                
                    ListIterator i = currentHandlers.listIterator();
                    try {
                        do {
                            freeHandler = (SocketHandler)i.next();
                        } while (freeHandler.isBusy());
                    } catch (NoSuchElementException e) {
                        // create new one
                        if (currentHandlers.size() < maxConn) {
                            freeHandler = (SocketHandler)handlerClass.newInstance();
                            currentHandlers.add(freeHandler);
                        }
                        else { // max handlers are created. wait for a while, then look again
                            Logger.warning("No free handlers left for "+handlerClass.getName()+" on port "+ port + "!");
                            Thread.sleep(2000);
                            continue;
                        }
                    }
                }
                try {
                    connectionSocket = serverSocket.accept();
                    if (keepListening) {
                        Logger.msg("SimpleTCPIPServer: Connection to "+freeHandler.getName()+" from "+
                            connectionSocket.getInetAddress());
                        freeHandler.setSocket(connectionSocket);
                        new Thread(freeHandler).start();
                    }
                } catch (InterruptedIOException ex1) { }// timeout just to check if we've been told to die

            }
            serverSocket.close();
            Logger.msg("SimpleTCPIPServer: Server closed for " + handlerClass.getName() +" on port "+ port);
        } catch(Exception ex) {
            Logger.error(ex);
            Logger.error("SimpleTCPIPServer.run(): Fatal Error. Listener for '"+handlerClass.getName()+"' will stop.");
            listener = null; --noServers;
            return;
        }
        listener = null;
        Logger.msg("SimpleTCPIPServer - Servers still running: "+--noServers);
    }
    
    public int getPort() {
        return port;
    }
}