[java]JavaSE基礎小項目:校園多人暢聊系統

這是一個基於JavaSE的小項目,從名字我們也能看出來這是個多人聊天系統。下面記錄一下整個項目的功能,設計思想以及所用到的知識,大家有興趣的話,也可以自己嘗試練習一下,也算是對SE的複習。

  • 項目名稱:校園多人暢聊系統
  • 項目描述:支持多人羣聊、私聊的網絡聊天系統
  • 使用技術:Java基礎、Socket編程
  • 項目功能:
    • 註冊
    • 私聊
    • 羣聊
    • 退出
  • 項目實現:
    • 服務端:採用線程池調度執行服務器與客戶端業務處理邏輯
    • 客戶端: 採用讀寫線程,分別處理交互服務與服務器數據接收

以上是項目總體的介紹,下面我們具體明確一下服務器端與客戶端的實現:
服務器端實現:
1,維護功能:維護所有在線的客戶端
2,註冊功能:將客戶端註冊名稱添加到服務器的客戶端集合裏
3,羣聊功能:客戶端發送消息,其餘所有客戶端都能接收到消息
4,私聊功能:客戶端與指定客戶端發送和接收數據
5,退出功能:從服務器客戶端集合中移除客戶端
客戶端實現:
1,註冊功能:創建Socket,給服務器發送註冊執行
2,羣聊功能:給客戶端發送和接收數據
3,私聊功能:客戶端指定客戶端(用戶)發送數據
4,退出功能:給服務器發送退出指令(消息)

由於我們項目中用到了一些Socket編程的知識,簡單說一下我們項目中用到的一些Socket知識:
ServerSocket :基站類,服務器Socket類
public ServerSocket(int port):在本機根據指定端口號創建服務器
public Socket accept():偵聽並接收連接到本服務的客戶端連接
此方法會一直阻塞,直到有一個客戶端成功連接,返回此連接。

Socket:客戶端類
public Socket(String host,int port):
根據指定Ip和端口號創建套接字並連接到遠程服務器端
public InputStream getInputStream() 返回此套接字的輸入流
public OutputStream getOutputStream() 返回此套接字的輸出流
有了以上方法就足以應對我們這個項目了。

第一步:要實現通信功能,我們要做的就是要讓客戶端能和服務器進行連接
我們將自己想象成一個服務器,我們應該先開啓連接功能,但具體有誰來鏈接我,我事先並不會知道。因此我可以把我的ip地址和端口號告訴大家,如果有誰想要來連接,拿着我的ip地址和端口號向我發送連接請求就行。
第二步,我們是一個多人聊天系統,自然不可能是一個單線程的,如果是單線程那就是大家輪流和服務器聊天,一個聊完了換下一個人。顯然我們需要用到多線程,要維護這麼多線程,自然需要用到線程池,而線程池有四種啓動方式,分析一下,我們決定採用一個固定線程大小的線程池來控制客戶端的連接數量。這裏我採用的是10個,具體數量大家可以根據自己的情況修改。只要你的電腦夠好。

//多線程服務器端
public class MultiThreadServer {
    public static void main(String[] args) {
        // 創建線程池,保存多個客戶端各自的線程
        final ExecutorService executorService = Executors.newFixedThreadPool(10);
        try {
            ServerSocket serverSocket = new ServerSocket(6666);
            System.out.println("服務器啓動..."+serverSocket.getLocalSocketAddress());
            // 等待不同線程連接
            System.out.println("等待客戶端連接");
            while(true){
            Socket client = serverSocket.accept();
            executorService.submit(new ExecuteClient(client));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第三步:服務器建立好連接後,就需要等待客戶端來連接了。客戶端自然不會說只是連接了服務器就好了,還需要向服務器發送數據和從服務器讀取數據。考慮到讀、寫這兩個過程是可以同時進行的,因此我們可以把客戶端的讀、寫過程用兩個線程來實現,以提高效率。

public class MultiThreadClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",6666);
            // 1.往服務器發送數據
            new WriteDataToServer(socket).start();
            // 2.從服務讀取數據
            new ReadDateFromServer(socket).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第四步:建立好連接,客戶端就可以向服務器發送消息了:這部分就比較簡單了,只是普通的IO操作。讀取服務器消息也是一樣的操作。

public class WriteDataToServer extends Thread{
    private final Socket client;
    public WriteDataToServer(Socket client) {
        this.client = client;
    }
    @Override
    public void run() {
        try {
            OutputStream clientOutput = client.getOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(clientOutput);
            Scanner scanner = new Scanner(System.in);
            while(true){
                System.out.println("請輸入消息");
                String message = scanner.nextLine();
                writer.write(message+"\n");
                writer.flush();
                if(message.equals("bye")){
                    // 表示客戶端要關閉
                    client.close();
                    break; //沒有這個,bye時,read會有異常,因爲已知在while裏等待輸入
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

第五步:由於目前我們是在控制檯進行聊天的,並沒有可視化界面,有按鈕可以讓你選擇羣聊私聊等。因此我們在這裏規定一下格式:
* 1.註冊:userName:< name >
* 2.私聊:private:< name > : < message >
* 3.羣聊:group:< message >
* 4.退出:bye
在明確了格式之後,我們服務器就可以對這些消息進行處理了
我們接收到客戶端的消息,先提取出用戶想要做什麼事情,通過匹配不同的格式,對客戶端進行不同的處理。代碼在次不做粘貼了。

整個項目源碼地址:
校園多人暢聊系統

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章