Java小程序之簡單多人聊天室的實現(山寨QQ前傳)
一、前言:
通過對Java服務器生猛上手的學習,已經基本明白了Java中通信的基本原理,以及服務器,ip,ip地址的概念;
我們思考下服務器到底是用來干嘛的呢?當多臺客戶端連上服務器以后,服務器需要提供的就是為連接進來的客戶端提供相應的服務;具體的來說就是處理不同客戶端發來的消息或者數據,然后把這些消息或者數據發送到另外的客戶端;服務器的目的就是正確轉發消息或者數據;
二、簡單多人聊天室的實現思路:
1、創建服務器, 等待客戶端的連接
2、客戶端連接進來以后,獲取輸入輸出流,利用輸入輸出流發送消息;
3、發送服務器連接成功的信息給客戶端,并提示客戶端輸入賬戶和密碼進行登錄
4、服務器接收客戶端發來的賬號和密碼,校驗成功后,提示登錄成功,開始多人聊天
難點:如何實現多人聊天? 定義一個容器:用于封裝所有的 ServerThread 線程對象,遍歷該容器中的對象,將消息轉發給每一個客戶端(自己可以除外)
問題: 當某個客戶端退出后,其他客戶端再發消息的時候,轉發就會報錯;
解決:當有客戶端退出時,將該客戶端從容器中移除;不在向該客戶端轉發消息;
三、 程序源代碼:
連接服務器類:
package com.huaxin.server;import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList;
public class Myserver {
public static ArrayList<ServerThread>list =new ArrayList<ServerThread>(); public void initServer() { try { //創建服務器對象,并指定端口號 ServerSocket server = new ServerSocket(9090); System.out.println("服務器已經建立......"); //不斷獲取客戶端的連接 while(true){ Socket socket =server.accept(); System.out.println("客戶端連接進來了......"); //當有客戶端連接進來以后,開啟一個線程,用來處理該客戶端的邏輯, ServerThread st = new ServerThread(socket); st.start(); //添加該客戶端到容器中 list.add(st); } } catch (Exception e) { e.printStackTrace(); } }}</pre>
服務器線程處理類:
package com.huaxin.server;import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket;
public class ServerThread extends Thread {
public Socket socket; public InputStream ins; public OutputStream ous; public ServerThread(Socket socket) { this.socket = socket; } public void run() { try { // 獲取輸入輸出流 ins = socket.getInputStream(); ous = socket.getOutputStream(); // 發送消息給客戶端 String msg = "welcome to zhou's server !"; sendMsg(ous, msg); // 發送要求登錄信息給客戶端 String userinfo = "please input your name:"; sendMsg(ous, userinfo); // 獲取客戶端輸入的用戶名 String userName = readMsg(ins); // 發送要求密碼信息給客戶端 String pwd = "please input your password:"; sendMsg(ous, pwd); // 獲取客戶端輸入的密碼 String pass = readMsg(ins); // 登錄驗證 boolean falg = loginCheck(userName, pass); // 校驗不通過時,循環校驗 while (!falg) { msg = "Fail to connect server......"; sendMsg(ous, msg); msg = "please check your name and password and login again....."; sendMsg(ous, msg); msg = "please input your name:"; sendMsg(ous, msg); // 獲取客戶端輸入的用戶名 userName = readMsg(ins); // 發送要求密碼信息給客戶端 msg = "please input your password:"; sendMsg(ous, msg); // 獲取客戶端輸入的密碼 pass = readMsg(ins); falg = loginCheck(userName, pass); } // 校驗成功后:開始聊天 msg = "successful connected..... you can chat with your friends now ......"; sendMsg(ous, msg); // 聊天處理邏輯 //讀取客戶端發來的消息 msg=readMsg(ins); //輸入bye結束聊天 while(!"bye".equals(msg)){ //給容器中的每個對象轉發消息 for (int i = 0; i <Myserver.list.size(); i++) { ServerThread st =Myserver.list.get(i); //不該自己轉發消息 if(st!=this){ sendMsg(st.ous, userName+" is say:"+msg); } } //等待讀取下一次的消息 msg=readMsg(ins); } } catch (Exception e) { System.out.println("客戶端不正常關閉......");// e.printStackTrace(); } //有異常后統一將流關閉 try { ins.close(); ous.close(); socket.close(); //將當前已經關閉的客戶端從容器中移除 Myserver.list.remove(this); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
// 校驗客戶端輸入的賬號和密碼的函數,由于沒有數據庫,暫時寫死了 public boolean loginCheck(String name, String pwd) { if (name.equals("zhou") && pwd.equals("zhou") || name.equals("user") && pwd.equals("pwd") || name.equals("huaxinjiaoyu") && pwd.equals("huaxinjiaoyu")) { return true; } return false; } // 發送消息的函數 public void sendMsg(OutputStream os, String s) throws IOException { // 向客戶端輸出信息 byte[] bytes = s.getBytes(); os.write(bytes); os.write(13); os.write(10); os.flush(); } // 讀取客戶端輸入數據的函數 public String readMsg(InputStream ins) throws Exception { // 讀取客戶端的信息 int value = ins.read(); // 讀取整行 讀取到回車(13)換行(10)時停止讀 String str = ""; while (value != 10) { // 點擊關閉客戶端時會返回-1值 if (value == -1) { throw new Exception(); } str = str + ((char) value); value = ins.read(); } str = str.trim(); return str; }}</pre>
函數入口類:
package com.huaxin.server;public class Test {
public static void main(String[] args) { Myserver ms = new Myserver(); ms.initServer(); }}</pre>
四、運行結果:(務必先啟動服務器)
第一次錯誤是由于未先開啟服務器:
![]()
輸入正確的用戶名和密碼進行登錄:
![]()
聊天界面:(中間有一次密碼輸入錯誤,但是還是可以再次輸入.......)
![]()
五、總結:
通過完成這個簡單的多人聊天的小程序,有一種說不出來的喜悅感;原來用Java來實現簡單的多人聊天這么簡單;自己也能寫出一個小小的聊天的軟件了呢......
接下來我們是不是可以寫個山寨版的QQ了呢......哈哈........拭目以待.......
來自:http://blog.csdn.net/bluesky_usc/article/details/54318498