程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java聊天室小程序-服務器代碼實現方面

Java聊天室小程序-服務器代碼實現方面

編輯:關於JAVA

服務器的實現效果:

1.輸入-help得到所有有關服務器操作的命令

2.輸入-run進入服務器各項內容初始化

3.輸入-stop斷開服務器

4.輸入-quit斷開服務器,並退出操作

5.服務器創建成功後,會通過單獨的線程運行監聽客戶端信息(listenLink)

6.服務器接收到數據後,會將數據移交至數據分析器(analyseMes)處理

7.當用戶確定連接並確定昵稱後,服務器將該用戶的地址及姓名存儲在 infoMemory中。

服務器的類與方法:

1.測試服務器創建:testServer(String ip,int port)

2.初始化服務器 :initServer(String ip,int port)

3.確定IP與Port :fixServerLink(String ip,int port)

4.信息監聽器  :listenLink()

5.數據分析器  :analyseMes(String mes)

6.獲取地址用戶名:getConsumerName(SocketAddress sa)

7.數據轉發器 :transforMes(String mes)

8.數據單項轉發器:transforMesSingle(SocketAddress adr,String mes)

9.停止服務器  :cutServer()

10.獲得幫助列表 :helpList()

11.錯誤提示方法 :errorTip(String str)

12.在主函數中進行相應操作

重點注意的地方:

與客戶端相仿,為了順利監聽信息,需要另一個線程運行信息監聽器

package com.sunspot.udp.chat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Scanner;
public class Server implements Runnable{
  private DatagramSocket server = null;
  private DatagramPacket getDatas = null;
  private InetAddress serverAddress = null;
  private int port = 0;
  //開始運行監聽的變量
  private boolean beStart = false;
  //用來測試服務器的變量
  private boolean test = true;
  //信息存儲器
  private Hashtable<String,SocketAddress> infoMemory = new Hashtable<String,SocketAddress>();

  /**
   * 測試服務器連接
   * @param ip
   * @param port
   * @return
   */
  public boolean testServer(String ip,int port) {
   this.initServer(ip, port);
   return test;
  }

  /**
   * 服務器初始化
   * @param ip
   * @param port
   */
  public void initServer(String ip,int port) {
   //確定IP與port輸入正確
   this.fixServerLink(ip,port);
   try {
    server = new DatagramSocket(this.port,serverAddress);
    System.out.println("!-The Server Initialization Success!");
    //可以開始運行變量
    beStart = true;
   } catch (SocketException  s) {
    //如果出現異常,則服務器測試不通過
    test = false;
    errorTip("!-The Server Initialization Fail!");
   } finally {

   }
  }

  /**
   * 確定服務器IP和端口信息
   * @param ip
   * @param port
   */
  private void fixServerLink(String ip,int port) {
   //判斷連接服務器的端口號
   //如果輸入命令為0,則為默認端口號9999
   //否則端口號為新端口號
   if(port == 0)
    this.port = 9999;
   else
    this.port = port;
   //判斷連接服務器的IP地址
   //如果輸入命令為0,則為默認的本地IP地址
   //否則為輸入的IP地址
   try {
    if(ip.equalsIgnoreCase("0"))
     this.serverAddress = InetAddress.getLocalHost();
    else
     this.serverAddress = InetAddress.getByName(ip);
   } catch (UnknownHostException u) {
    errorTip("!-Sorry, IP address you put is not currect!");
   }
  }

 
  /**
   * 監聽信息
   *
   */
  public void listenLink() {
   byte[] buf = new byte[1024];
   String mes = null;
   try {
    getDatas = new DatagramPacket(buf,buf.length);
    System.out.println("!-The Server starts listenning to message.");
    while(beStart) {
     server.receive(getDatas);
     mes = new String(buf,0,getDatas.getLength());
     //將獲取的數據傳遞至數據分析器
     this.analyseMes(mes);
    }
   } catch (IOException e) {
    errorTip("!-The Server Can not receive message");
   }
  }

  /**
   * 數據分析器,給予相應處理
   * @param mes
   */
  private void analyseMes(String mes) {
   //獲取當前客戶端的地址:
   SocketAddress adr = getDatas.getSocketAddress();

   //-test:進行服務器與客戶端的連接測試
   //若成功,則將該客戶端發送成功消息
   if(mes.trim().equalsIgnoreCase("-test")) {
    transforMesSingle(adr,"-test: !-From Server:Succeed in Testing.");
   }

  
   //-quit:接受客戶端退出信息
   //將該用戶的退出信息轉發至所有在線成員
   else if(mes.trim().equalsIgnoreCase("-quit")) {
    String name = this.getConsumerName(adr);
    System.out.println(name+"//"+adr+" quit! ");
    transforMes("* "+name+"退出聊天室");
    infoMemory.remove(name);
   }

   //-getList:接受客戶端獲取列表的請求
   //將所有用戶連接為字符串的形式,如:"-getList,用戶1,用戶2...用 戶n"
   else if(mes.trim().equals("-getList")) {
    StringBuffer list = new StringBuffer();
    list.append("-getList,");
    Enumeration<String> names = infoMemory.keys();
    while (names.hasMoreElements()) {
     list.append(names.nextElement()+",");
    }
    transforMesSingle(getDatas.getSocketAddress(),
      list.toString());
   }

   //-to:接受客戶端請求,將信息轉發給相應客戶
   //如果目標客戶不存在,則向請求客戶發送相應消息
   else if(mes.indexOf("-to ") != -1 && mes.startsWith("- to ")) {
    String main = mes.substring("-to ".length(),mes.length ());
    String toName = main.substring(0,main.indexOf(" "));
    String name = this.getConsumerName(adr);
    String con = name+" say to you :"+main.substring (toName.length()+1,main.length());
    if(!infoMemory.containsKey(toName))
     transforMesSingle(adr,
       "!-The message can not be recevie by whom you send for,please check out.");
    else
     transforMesSingle(infoMemory.get(toName),con);
   }

   //-nick:接受客戶端登錄請求
   //如果輸入的匿名不存在,則登記該用戶與infoMemory
   //如果存在則返回相應提示
   else if(mes.indexOf("-nick ") != -1 && mes.startsWith ("-nick ")) {
    String nickName = mes.substring("-nick ".length(), mes.length());
    if(infoMemory.containsKey(nickName))
     transforMesSingle(adr,
       "-nick: !-The nickname you post is already exist,please try others.");
    else {
     infoMemory.put(nickName,adr);
     transforMes("Welcome "+nickName +" to Sunspot Chat!");
     System.out.println(nickName+"//"+adr.toString()+" succeed in lanuching.");
    }
   }

   //一般消息將會轉發至所有用戶
   else {
    String name = this.getConsumerName(adr);
    transforMes(name+": "+mes);
   } 
  }

  /**
   * 通過地址得到用戶的昵稱
   * 由於Hashtable無法通過Value獲取Key,所有專門寫該方法
   * @param sa
   * @return
   */
  private String getConsumerName(SocketAddress sa) {
   Enumeration<String> names = infoMemory.keys();
   String name = null;
   while (names.hasMoreElements()) {
    String temp = names.nextElement();
    SocketAddress adrs = infoMemory.get(temp);
    //進行比較
    if (sa.equals(adrs)) {
     name = temp;
     break;
    }
   }
   return name;
  }

  /**
   * 向所有的用戶發送數據
   * @param mes
   */
  public void transforMes(String mes) {
   byte[] buf = mes.getBytes();
   DatagramPacket sendDatas = null;
   Enumeration<SocketAddress> all = infoMemory.elements ();
   try {
    while (all.hasMoreElements()) {
     sendDatas = new DatagramPacket (buf,buf.length,all.nextElement());
     server.send(sendDatas);
    }
   } catch (SocketException s) {
    errorTip("!-The feedback address is error!");
   } catch (IOException i) {
    errorTip("!-Can not send message!");
   }
  }

  /**
   * 向單個用戶發送數據
   * @param adr
   * @param mes
   */
  public void transforMesSingle(SocketAddress adr,String mes) {
   byte[] buf = mes.getBytes();
   try {
    DatagramPacket sendDatas = new DatagramPacket (buf,buf.length,adr);
    server.send(sendDatas);
   } catch (SocketException s) {
    errorTip("!-The feedback address is error!");
   } catch (IOException i) {
    errorTip("!-Can not send message!");
   }
  }

  /**
   * 斷開連接
   *
   */
  public void cutServer() {
   beStart = false;
   if(server != null)
    server.close();
   System.out.println("!-The server is done.");
  }

  public void helpList() {
   System.out.println(
     "-help"+"  獲取服務器相應操作的幫助"+"\n"+
     "-run "+"  運行服務器,並同時建立信息監聽"+"\n"+
     "-stop"+"  停止服務器"+"\n"+
     "-quit"+"  停止服務器,並退出命令"+"\n"
   );
  }

  /**
   * 線程
   */
  public void run() {
   listenLink();
  }

  /**
   * 主要操作
   * @param args
   */
  public static void main(String[] args) {
   Server ser = new Server();
   String getIp = null;
   int getPort = 0;

   //建立輸入
   Scanner input = new Scanner(System.in);
   System.out.println("!-Please input server command:");

   //開始輸入
   String command = null;
   //如果輸入quit將斷開連接,並退出操作
   while (!(command = input.next()).equalsIgnoreCase("-quit")) {
    //獲取幫助
    if(command.equalsIgnoreCase("-help")) {
     ser.helpList();
    }

    //初始化服務器
    if (command.equalsIgnoreCase("-run")) {
     boolean goon = true;
     while (goon) {
      System.out.println("1.輸入服務器的IP地址,默認輸入數字0: ");
      getIp = input.next();
      System.out.println("2.輸入服務器的端口號,默認輸入數字0: ");
      try {
       getPort = input.nextInt();
      } catch (Exception e) {
       System.out.println("!-The port style is not currect!");
      }
      //測試服務器創建,如果成功則同時為信息監聽器建立線程
      System.out.println("!-創建服務器並運行...");
      if (ser.testServer(getIp, getPort)) {
       new Thread(ser).start();
       goon = false;
      } else
       System.out.println("!-服務器創建失敗,請檢查!");
     }
    }

    //關閉服務器
    if (command.equalsIgnoreCase("-stop")) {
     ser.cutServer();
    }
   }
   input.close();
   ser.cutServer();
  }

  /**
   * 錯誤提示
   * @param str
   */
  public static void errorTip(String str) {
   System.out.println("-----------------\n"+str+"\n-------------- ---");
  }
}

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved