一、羣聊服務器的實現基本功能
- 當客戶機連接服務器,服務器要求客戶機輸入用戶名和密碼
- 當輸入的用戶名和密碼與服務器所保存的賬號一致登錄成功,否則斷開
- 登錄成功後,給其他客戶機提示信息,顯示在線人數
- 登錄成功的客戶機可以給服務器發送消息,其他客戶端也會收到消息
實現基本流程
程序設計
(一)服務器端
1)ChatServer類:創建服務器並啓動等待連接
2)ServerThread類:處理Socket對象線程類,每連接一個客戶機就創建一個線程
3)DaoTools類:數據的訪問和驗證類,負責生成模擬數據並驗證客戶端賬號
4)ChatTools類:服務器輔助類,將客戶機發送的消息轉發給其他客戶
5)UserInfo類:用戶數據模型,每一個UserInfo類對象存儲一個用戶的賬號信息
代碼實現:
https://github.com/zhenglimei/chatServer
效果展示:
小結:
- 程序中的阻塞機制
阻塞是指當程序執行某行代碼時會停止執行知道這行代碼執行完畢,其中
Socket client = server.accept();//等待客戶機進入
accept()方法會一直停住,直到有一個客戶機連接進來 纔會返回一個Socket對象。
另外一個阻塞的地方就是,從網絡讀取數據時,如以下代碼:
//直接從InputStream中讀取數據: int i=ins.read();//或將輸入流ins封裝爲可以讀取一行字符串,也就是以\r\n結尾的字符串
BufferedReader brd=new BufferedReader(new InputStreamReader(ins))
String pwd=brd.readLine();
這裏read()方法會阻塞直到讀到一個字節:readLine()方法也會阻塞,直到客戶端發送一個回車字符,纔會將讀取的字符串返回,對於會阻塞的代碼,一般要放到獨立的線程中執行,這樣不致於阻塞其他方法的調用
2. 內存泄露問題
Java雖然有GC機制,但是也會存在內存泄露的問題,在這個案例中,每登錄一個客戶機就將對應的ServerThread對象放入ChatTools隊列中,這樣隨着對象的增加,服務器就可能會奔潰。
二、羣聊客戶端實現
效果展示:
[詳細代碼] (https://github.com/zhenglimei/chatServer)