Voici un serveur simple permettant des connections multiples. Il
est à utiliser plutôt pour des tests, non pas pour de la production.
L'exemple suivant étends les fonctions de ce serveur: plus
d'informations peuvent être obtenues à l'adresse suivante:
technochump@netscape.net.
import java.io.*;
public class nTalk extends esKernel {
public static void main(String argv[]) {
new nTalk(argv);
}
nTalk(String argv[]) {
startServer(argv);
}
public void serverStarted() { }
public void clientLogin(int lPID) {
clientSend("Welcome User", lPID);
disconnectClient(lPID);
}
public void clientLogout(int lPID) { }
public void clientRecieve(String lineIn, int lPID) { }
}
Le code proprement dit est le suivant:
import java.io.*;
import java.net.*;
public class esKernel extends Thread {
protected int MAXIMUMSOCKETS = 200;
protected Thread Samurai[];
protected Thread Ninja;
protected Socket client[];
protected BufferedReader clientInput[];
protected PrintStream clientOutput[];
protected ServerSocket server;
protected String NAME = "SLT(Socket Transit Lite)";
protected String VERSION = "062600MN";
protected String BUILD = "21";
public int OWNED = 1, FREE = 0;
public int clientPID[];
public int serverPORT = 1060;
public int curPID = 0;
public int cachedPID = 0;
public int freeSOCKETS = 0;
public boolean dontLoad = false, quietMode = false;
public void startServer(String argv[]) {
int lPID = curPID;
for(int I = 0; I < argv.length; I+=2) {
if(argv[I].equals("--help")) showHelp();
if(argv[I].equals("--version")) showVersion();
if(argv[I].equals("--quiet")) setQuiet();
if(argv[I].equals("--lazy")) {
if(I + 1 >= argv.length) {
showHelp();
} else {
buildLazy(argv[I + 1]);
}
}
if(argv[I].equals("--port")) {
if(I + 1 >= argv.length) {
showHelp();
} else {
setPort(Integer.parseInt(argv[I + 1]));
}
}
if(argv[I].equals("--sockets")) {
if(I + 1 >= argv.length) {
showHelp();
} else {
setSockets(Integer.parseInt(argv[I + 1]));
}
}
}
if(dontLoad) return;
loadSockets();
statusMessage();
serverStarted();
/** Start up our command line Input Stream **/
Ninja = new Thread(this);
Ninja.start();
/** ClientPid[0] needs to be set to OWNED **/
curPID = getClientPID();
try {
server = new ServerSocket(serverPORT, MAXIMUMSOCKETS, null);
} catch(IOException ie) {
showError(0, -1);
System.exit(0);
}
while(true) {
try {
client[lPID] = server.accept();
} catch(IOException ie) {
showError(1, lPID);
}
Samurai[lPID] = new Thread(this);
try {
clientInput[lPID] =
new BufferedReader(new InputStreamReader(client[lPID].getInputStream()));
clientOutput[lPID] = new PrintStream(client[lPID].getOutputStream());
} catch(IOException ie) {
showError(2, lPID);
}
/** This is my attempt to limit connections **/
if(lPID > MAXIMUMSOCKETS - 3) {
clientOutput[lPID].println("SORRY, THIS SERVER IS CURRENTLY FULL.");
clientOutput[lPID].flush();
showError(5, lPID);
disconnectClient(lPID);
} else {
Samurai[lPID].start();
}
curPID = lPID;
lPID = getClientPID();
}
}
public void run() {
int lPID = curPID;
String lineIn = "";
if(Thread.currentThread() == Ninja) {
startCommandLineStream();
}
clientLogin(lPID);
while((lineIn != null) && (clientInput[lPID] != null)) {
try {
lineIn = clientInput[lPID].readLine();
} catch(IOException ie) {
showError(3, lPID);
break;
}
if(lineIn != null)
parseDataInput(lineIn, lPID);
}
disconnectClient(lPID);
}
public int getClientPID() {
for(int I = 0; I < MAXIMUMSOCKETS; I++) {
if(clientPID[I] == FREE) {
clientPID[I] = OWNED;
cachedPID = I;
freeSOCKETS--;
return I;
}
}
cachedPID = -1;
return -1;
}
public int disconnectClient(int dPID) {
if(clientPID[dPID] == FREE) return -1;
try {
if(clientInput[dPID] != null)
clientInput[dPID].close();
if(clientOutput[dPID] != null)
clientOutput[dPID].close();
if(client[dPID] != null)
client[dPID].close();
} catch(IOException ie) {
showError(4, dPID);
}
clientInput[dPID] = null;
clientOutput[dPID] = null;
Samurai[dPID] = null;
client[dPID] = null;
clientPID[dPID] = FREE;
freeSOCKETS++;
if(!quietMode) {
System.out.println("Client Disconnected Successfuly.");
System.out.println("Client PID # " + String.valueOf(dPID) + " now FREE.");
}
clientLogout(dPID);
return dPID;
}
public void loadSockets() {
Samurai = new Thread[MAXIMUMSOCKETS];
client = new Socket[MAXIMUMSOCKETS];
clientInput = new BufferedReader[MAXIMUMSOCKETS];
clientOutput = new PrintStream[MAXIMUMSOCKETS];
clientPID = new int[MAXIMUMSOCKETS];
freeSOCKETS = MAXIMUMSOCKETS;
}
public void showError(int ErrorMessage, int lPID) {
String Error[] = new String[6];
String clientID = "";
if(quietMode) return;
if(lPID > -1)
clientID = "CLIENT # " + String.valueOf(lPID);
Error[0] = "Error 0:\n" + clientID +
"\nDESCRIPTION: Can't Open Port " +
String.valueOf(serverPORT) +
".\nSOLUTION: Try Restarting Server with --port x.\nRESULT: KILLED SERVER!!";
Error[1] = "Error 1:\n" + clientID +
"\nDESCRIPTION: Server is no Longer Accepting Connections.\n
SOLUTION: Restart Server.\nRESULT: No Action Taken.";
Error[2] = "Error 2:\n" + clientID +
"\nDESCRIPTION: Can't establish a Consistant Connection with Client.\n
SOLUTION: Attempt to Kill Client.\nRESULT:";
Error[3] = "Error 3:\n" + clientID +
"\nDESCRIPTION: Client Sending Bogus Data!\n
SOLUTION: Attempting to Kill Client!!\nRESULT:";
Error[4] = "Error 4:\n" + clientID +
"\nDESCRIPTION: Can't Terminate Connection with Client.\n
SOLUTION: Preforming Explicit Kill!!\nRESULT:";
Error[5] = "Error 5:\n" + clientID +
"\nDESCRIPTION: SERVER FULL CAN'T ACCEPT CONNECTION\n
SOLUTION: Kill USER\nRESULT:";
System.out.println(Error[ErrorMessage]);
}
public void statusMessage() {
System.out.println("<------------------------- STATUS ------------------------->");
System.out.println(" [" + NAME + "]");
System.out.println(" VERSION " + VERSION + " BUILD: " + BUILD);
System.out.println(" USING PORT: " + String.valueOf(serverPORT));
System.out.println(" CLIENTS: MAX -> " + String.valueOf(MAXIMUMSOCKETS) +
" CURRENT -> " + String.valueOf(MAXIMUMSOCKETS - freeSOCKETS) +
" FREE PIDS -> " + String.valueOf(freeSOCKETS));
System.out.println("<---------------------------------------------------------->");
}
public void showHelp() {
System.out.println("\n[" + NAME + "]");
System.out.println("Version " + VERSION + " BUILD " + BUILD);
System.out.println("Chris Higgins 2000\n");
System.out.println("--help -> Shows this Message");
System.out.println("--sockets x -> Where x equals Maximum Sockets Allowed
(expressed as an Integer)");
System.out.println("--quiet -> Don't show any Messages");
System.out.println("--port x -> Where x equals port to host
(expressed as an Integer)");
System.out.println("--version -> Shows version Number");
System.out.println("--lazy s -> Build a templet-ready java file called s.");
dontLoad = true;
}
public void showVersion() {
System.out.println("\n[" + NAME + "]");
System.out.println("Version " + VERSION + " BUILD: " + BUILD);
System.out.println("Chris Higgins <technochump@netscape.net>");
System.out.println("2000");
dontLoad = true;
}
public void setPort(int newPORT) {
serverPORT = newPORT;
}
public void setSockets(int newSOCKETS) {
MAXIMUMSOCKETS = newSOCKETS;
}
public boolean setQuiet() {
if(quietMode) {
quietMode = false;
} else {
quietMode = true;
}
return quietMode;
}
public void buildLazy(String fileName) {
System.out.println("import java.io.*;\n");
System.out.println("public class " + fileName + " extends esKernel {\n");
System.out.println("public static void main(String argv[]) {");
System.out.println("new " + fileName + "(argv);");
System.out.println("}\n");
System.out.println(fileName + "(String argv[]) {");
System.out.println("startServer(argv);");
System.out.println("}\n");
System.out.println("public void serverStarted() { \n\n}\n");
System.out.println("public void clientLogin(int lPID) { \n\n}\n");
System.out.println("public void clientLogout(int lPID) { \n\n}\n");
System.out.println("public void clientRecieved(String lineIn, int lPID) { \n\n}\n");
System.out.println("}");
dontLoad = true;
}
public void parseDataInput(String lineIn, int pPID) {
if(!quietMode)
System.out.println(lineIn + "<CLIENT # " + String.valueOf(pPID) + ">");
clientRecieve(lineIn, pPID);
}
/*** Used as an Ancestry Reference ***/
public void serverStarted() {
}
/*** Used as an Ancestry Reference ***/
public void clientLogin(int lPID) {
}
/*** Used as an Ancestry Reference ***/
public void clientLogout(int lPID) {
}
/*** Used as an Ancestry Reference ***/
public void clientRecieve(String lineIn, int pPID) {
}
public void clientSend(String isMessage, int pPID) {
if((clientPID[pPID] != OWNED) || (pPID == cachedPID)) return;
clientOutput[pPID].println(isMessage);
clientOutput[pPID].flush();
}
/***
Takes care of Admin Inputs from the Command Line While the Server is
Running
***/
public void startCommandLineStream() {
BufferedReader serverCommandLine;
serverCommandLine = new BufferedReader(new InputStreamReader(System.in));
while(true) {
try {
parseCommandLineInput(serverCommandLine.readLine());
} catch(IOException ie) { break; }
}
}
public void parseCommandLineInput(String lineIn) {
if(lineIn.startsWith("/quit"))
System.exit(0);
if(lineIn.startsWith("/broadcast")) {
for(int I = 0; I < MAXIMUMSOCKETS; I++) {
clientSend(lineIn.substring(11, lineIn.length()), I);
}
System.out.println("# Message Broadcasted.");
}
if(lineIn.startsWith("/quiet")) {
if(setQuiet()) {
System.out.println("# Quiet Mode Enabled.");
} else {
System.out.println("# Quiet Mode Disabled.");
}
}
if(lineIn.startsWith("/status"))
statusMessage();
if(lineIn.startsWith("/kill"))
disconnectClient(Integer.parseInt(lineIn.substring(6, lineIn.length())));
if(lineIn.startsWith("/help")) {
System.out.println("/***** Command Line Help *****/");
System.out.println("/quit -> Used to terminate server.");
System.out.println("/broadcast x -> Broadcast Message to all Users.");
System.out.println("/kill i -> Disconnect user <i>.");
System.out.println("/help -> Display this Message.");
System.out.println("/quiet -> Enter or disable Quiet Mode");
System.out.println("/trace i -> Trace user <i>.");
System.out.println("/message i -> Send Message to user <i>.");
System.out.println("/who -> Show all used PIDS.");
System.out.println("/status -> Show current server status.");
}
}
}
|