聊天軟件服務器端

import java.net.*;
//import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
//import java.util.Map;
import java.io.*;

public class Server {
    List<ClientServer> allClients = new LinkedList<ClientServer>();  
    ServerSocket server = null;
     boolean started = false;
    ClientListenner cl = null;
  
    //////////////////////////客戶端Control + C 時發生NullPointerException,在線程ClientServer處
     public static void main(String[] args) {
   new Server().start();
    }

     /*
  * 服務器端構造函數
  * 將監聽接口綁定到本地端口8888處
  */

     public Server(){
   try {
      server = new ServerSocket(8888);
  } catch (BindException e) {
      System.out.println( "端口使用中");
      System.out.println( "請關掉相關程序並從新運行服務器!");
      System.exit(0);
  } catch (IOException e) {
      e.printStackTrace();
      System.exit(0);
  }  
    }
  
     /*
  * 服務器啓動函數
  */

     public void start() {
  System.out.println( "Server Starts!");
  started = true;
  cl = new ClientListenner(server);
  cl.start();
  readCommand();
    }
  
     /*
  * 服務器關閉函數
  */

     public void shutdown() {
  started = false;
  cl.close();
  System.out.println( "server shutdown");
    }

     /*
  * 讀取控制檯輸入命令函數
  */

     public void readCommand() {
  BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
  String str = null;
   try{
       while(started){
    str = br.readLine();
    excuteCommand(str);
      }
  } catch (NullPointerException e){/////////////Control+C時發生的異常
      System.out.println( "服務器中斷");
  } catch (IOException e) {
      e.printStackTrace();
  } finally {
       try{
    br.close();
      } catch (IOException e1){
    e1.printStackTrace();
      }
  }
    }
  
     /*
  * 執行控制檯命令函數
  */

     public void excuteCommand(String command) {
   if (command.toLowerCase().equals( "useramount")) {
      System.out.println(getUserAmount());
  } else if (command.toLowerCase().equals( "usernames")) {
      System.out.println(getAllUserName());
  } else if (command.toLowerCase().equals( "userinfo")) {
      System.out.println(getUserInfo());
  } else if (command.toLowerCase().equals( "help")) {
      System.out.println(getHelp());
  } else if (command.toLowerCase().equals( "shutdown")){
      shutdown();
  }
    }
  
     /*
  * 獲取當前服務器在線人數函數
  */

     public String getUserAmount() {
   return "當前在線用戶人數爲: " + allClients.size() + "\n";
    }
  
     /*
  * 獲取當前服務器在線用戶的名字
  */

     public String getAllUserName(){
  StringBuffer sb = new StringBuffer();
  sb.append( "當前在線用戶是:");
  sb.append( "\n");
   for ( int i = 0; i < allClients.size(); i++) {
      sb.append(allClients.get(i).userName);
  }
   return sb.toString();
    }
  
     /*
  * 獲取當前服務器在線用戶的信息
  * 包括用戶個數和用戶姓名
  */

     public String getUserInfo() {
  StringBuffer sb = new StringBuffer();
  sb.append(getUserAmount());
  sb.append(getAllUserName());
   return sb.toString();
    }
  
     /*
  * 提供服務器命令信息
  */

     public String getHelp() {
  StringBuffer sb = new StringBuffer();
  sb.append( "useramount      顯示當前在線用戶人數\n");
  sb.append( "usernames      顯示當前在線用戶的名字\n");
  sb.append( "userinfo      顯示當前在線用戶的人數及姓名");
   return sb.toString();
    }
  
     /*
  * 監聽客戶端鏈接線程
  * 爲每個新鏈接的客戶端提供一個服務器線程
  */

     class ClientListenner extends Thread {
  ServerSocket s = null;
  
   public ClientListenner(ServerSocket s) {
       this.s = s;
  }
  
  @Override
   public void run() {
       try{
     while (started) {
        Socket c_server = s.accept();
        ClientServer cs = new ClientServer(c_server);
        allClients.add(cs);
        System.out.println(cs.userName + "登陸");
         new Thread(cs).start();
    }
      } catch (SocketException e){
    System.out.print("");//////////////////客戶端關閉的時候發生異常
      } catch (IOException e){
    e.printStackTrace();
      }  
  }
  
   public void close() {
       try {
    started = false;
     if (s != null)
        s.close();
      } catch (IOException e) {
    e.printStackTrace();
      }
  }
    }

     /*
  * 服務器服務線程類
  * 接受客戶端的輸入,並將得到到信息發送到全部的客戶端
  */

     class ClientServer implements Runnable {
  Socket c_server = null;
  ClientServer cs = null;
   boolean connected = false;
  DataOutputStream dout = null;
  DataInputStream din = null;
  String userName = null;  

   /*
   * 構造函數
   * 初始化從客戶端得到的socket、創建服務器與客戶端的鏈接、初始化輸入輸出流
   */

   public ClientServer(Socket s) {
      c_server = s;
      connected = true;
       try {
    din = new DataInputStream(s.getInputStream());
    dout = new DataOutputStream(s.getOutputStream());
      } catch (IOException e) {
    e.printStackTrace();
      }
      register(receiveMessage());
  }

   /*
   * 消息發送函數
   * 向客戶端發送消息
   */

   public void sendMessage(String message) {
       try {
    dout.writeUTF(message);
    dout.flush();
      } catch (IOException e) {
    e.printStackTrace();
      }
  }

   /*
   * 消息接受函數
   * 從客戶端接受消息
   */

   public String receiveMessage() {
      String message = null;
       try{
    message = din.readUTF();
      } catch (EOFException e){
    System.out.println( "客戶端中斷!");
      } catch (SocketException e){
    System.out.print("");//////////////////客戶端關閉的時候發生異常
      } catch (IOException e){
    e.printStackTrace();
      }
       return message;  
  }
  
  @Override
   public void run() {
      String str = null;
    
      sendMessage( "server says:hello,I am the server!");
       while (connected) {
    str = receiveMessage();
    interpret(str);
      }
      close();
  }
  
   /*
   * 服務線程類關閉函數
   * 關閉相關輸入輸出流、socket
   */

   public void close() {
       try {
     if (dout != null)
        dout.close();
     if (din != null)
        din.close();
     if (c_server != null)
        c_server.close();
     if (allClients.contains( this))
        allClients.remove( this);
      } catch (IOException e) {
    e.printStackTrace();
      }  
  }

   /*
   * 消息解釋函數
   * 根據消息類型選擇執行相關操做
   */

   public void interpret(String str) {
       boolean bToAll = true;
       switch (strType(str)) {
       case 0:
    sendToClient(bToAll, str);
     break;
       case 1:
    bToAll = changePeople(str);
     break;
       case 2:
    excuteUserCommand(str);
     break;
       default:
     break;
      }  
  }
  
   /*
   * 註冊函數
   * 服務器段記錄登陸用戶名
   */

   private void register(String name){
      userName = name;
  }
  
   /*
   * 命令執行函數
   * 根據客戶端發送過來的指令執行相關操做
   */

   private void excuteUserCommand(String str){
      String command = str.substring(1);
       if (command.equals( "userinfo")){
    sendMessage(getUserInfo());
      }
       else if(command.equals( "help")){
    sendMessage(getHelp());
      }
       else if(command.equals( "bye")){
    connected = false;
    System.out.println(userName + "退出了");
    allClients.remove( this);
      }
  }
  
   /*
   * 消息轉發對象轉換函數
   * 選擇單對單發送消息,或者羣發消息
   */

   private boolean changePeople(String str) {
      String name = str.substring(1);
       if (name.equals( "all")) {
     return true;
      } else {
     for ( int i = 0; i < allClients.size(); i++) {
         if (name.equals(allClients.get(i).userName)) {
      cs = allClients.get(i);
       return false;
        }
    }
      }
       return true;
  }
  
   /*
   * 消息解釋函數
   * 根據消息起始字符調用返回整型值
   * @return 1 表示對象轉換
   * @return 2 表示獲取服務器信息
   * @return 0 表示正常消息發送語句
   */

   private int strType(String str){
       if (str.startsWith( "-"))
     return 1;
       else if(str.startsWith( "?"))
     return 2;
       else  
     return 0;
  }
  
   /*
   * 消息發送函數
   * 根據傳入的參數,將消息傳給羣發或者發送給指定客戶端
   */

   private void sendToClient( boolean bToAll,String str) {
       if (bToAll) {
     for ( int i = 0; i < allClients.size(); i++) {
        allClients.get(i).sendMessage( this.userName + " says: " + str);  
    }
      } else {
    cs.sendMessage(cs.userName + " says: " + str);       }   }       } }
相關文章
相關標籤/搜索