2012年7月27日 星期五

JAVA multi-client server


MUDApplication.java
package neo.mudserver;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;


public class MUDApplication {
 public static void main(String[] args) throws InterruptedException, IOException {
  Server myServer = new Server(2222,50,10);
  long timestamp;
  long sleep;
  while(true){
   timestamp = System.currentTimeMillis();
   Client newclient = myServer.acceptNewConnetcion();
   if(newclient != null){
    Date date = new Date();
    System.out.println(date.toString()+"建立了新連線");
    myServer.flush();
   }
   ArrayList<CommandSet> cmds = null;
   cmds = myServer.readMessageFromClient();
   doProcessCommandSet(cmds);
   myServer.flush();
   sleep = 250 - (System.currentTimeMillis() - timestamp);
   if (sleep > 0)
    Thread.sleep(sleep);
  }
 }
 public  static void doProcessCommandSet(ArrayList cmds){
  Iterator<CommandSet> i = cmds.iterator();
  while(i.hasNext()){
   CommandSet command = i.next();
   Client client = command.client;
   String commandmessage = command.commandMessage;
   System.out.println("收到client("+client.ID+")端傳來的訊息:"+commandmessage);
   String colorWhite = (char) 27 + "[1;37m";
   client.write(colorWhite+"Server收到你傳去的message:\""+commandmessage+"\"\r\n");
   if(commandmessage.equalsIgnoreCase("quit")){
    try {
     client.close();
    } catch (IOException e) {
     System.out.println("嘗試關閉client("+client.ID+")端連線失敗");
    }
   }
  }
 }
}


Server.java
package neo.mudserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Iterator;

public class Server {
 ServerSocket serversocket;
 ArrayList<Client> clients;
 int port;
 int serverSocketTimeout;
 int clientSocketTimeout;
 public Server(int port, int serverSocketTimeout,int clientSocketTimeout){
  try {
   this.port = port;
   this.serverSocketTimeout = serverSocketTimeout;
   this.clientSocketTimeout = clientSocketTimeout;
   System.out.println("監聽"+port+"埠:");
   serversocket = new ServerSocket(port);
   clients = new ArrayList<Client>();
   serversocket.setSoTimeout(serverSocketTimeout);  //注意要設timeout時間server才不會pending在那裏
  } catch (IOException e) {
   System.out.println(+port+"埠被占用,關閉連線");
  }
 }
 public Client acceptNewConnetcion() throws IOException{
  Client client = null;
  try {
   Socket socket = serversocket.accept();
   client = new Client(this, clients.size(),socket);
   client.socket.setSoTimeout(clientSocketTimeout); //不設timeout的話Server的readMessageFromClient做client.read()就會hold在那裏
   clients.add(client);
   String colorCyan = (char) 27 + "[1;36m";
   client.write(colorCyan+"跟Server建立了連線\r\n");
  } catch (SocketTimeoutException e) {
   //當TimeOut時繼續做acceptNewConnetcion之後的動作所以這裡為空指令
  }
  return client;
 }
 public void flush(){
  Iterator<Client> i = clients.iterator();
  while (i.hasNext()){
   Client currectClient = i.next();
   try {
    currectClient.flush();
   } catch (IOException e) {
    System.out.println("client("+currectClient.ID+")不能被flush");
   }  
  }
 }
 public ArrayList<CommandSet> readMessageFromClient() throws IOException{
  ArrayList<CommandSet> cmds= new ArrayList();
  Iterator i = clients.iterator();
  while(i.hasNext()){
   String inputMessage;
   Client currectClient = i.next();
   try {
    currectClient.read();
   } catch (SocketTimeoutException e) {
    //當TimeOut時視為沒有輸入這裡為空指令
   }
   inputMessage = currectClient.inBuffer;
   if (inputMessage != null) cmds.add(new CommandSet(currectClient, inputMessage));
  }
  return cmds;
  
 }
}

Client.java
package neo.mudserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

public class Client {
 enum State{promptName,promptNameVerivfy,connected};
 int ID;
 Server server;
 Socket socket;
 StringBuffer outBuffer;
 String inBuffer;
 public Client(Server server, int cliendID, Socket socket) throws SocketException{
  this.ID = cliendID;
  this.server = server;
  this.socket = socket;
  this.outBuffer = new StringBuffer();
  this.inBuffer = null;
 }
 public void write(String message){
  this.outBuffer.append(message);
 }
 public void flush() throws IOException {
  OutputStream outputstream = socket.getOutputStream(); //socket是從server來的所以對server而言是output
  outputstream.write(outBuffer.toString().getBytes());
  outBuffer.setLength(0); //命令輸出了之後要記得清零
 }
 public void read() throws IOException,SocketTimeoutException{
  inBuffer = null;
  BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  inBuffer = br.readLine();
 }
 public void close() throws IOException{
  socket.close();
  server.clients.remove(this);
 }
}

CommandSet.java
package neo.mudserver;

public class CommandSet {
 Client client;
 String commandMessage;
 public CommandSet(Client client, String message){
  this.client = client;
  this.commandMessage = message;
 }
}

沒有留言:

張貼留言