Java之簡單的聊天工具

來源:互聯網
上載者:User

       今天整理資料的時候,找出自己幾年前剛學Java時做過的一個簡易的聊天工具,有伺服器也有用戶端,能發送文字訊息和檔案,但是使用者上線並未存入資料庫,而只是簡單的緩衝在伺服器的一個數組中,所以,只要伺服器一關閉,所有使用者資料都會消失,介面是用第三方包,很簡單,有點醜陋,不喜勿噴。


源碼地址:http://download.csdn.net/detail/weidi1989/5810475

(GB2312編碼方式,基於JDK1.7編譯,如果直接匯入eclipse出問題,請自行百度解決,3Q)


在運行代碼之前,我們需要先作一下配置:

①伺服器配置:如所示,找到Constants.java檔案開啟,將SERVER_IP改成你電腦對應的ip地址即可,連接埠視情況改變。


②用戶端配置:同樣如所示,找到Constants.java類,將SERVER_IP以及SERVER_PORT改成與伺服器對應(這個很重要)


③先運行伺服器,再運行用戶端。



下面,我們來看看具體:

1.先運行伺服器,然後運行用戶端,即可顯示如下介面,同一區域網路內的使用者,會自動添加到好友名單中。



2.測試文字交談,只是簡單發送文字訊息,醜陋程度就不提了



3.測試檔案發送與接收,發送的檔案內容請忽視哦!



簡單的思路分析:

①伺服器監聽一個連接埠,時時等待使用者的串連,當有使用者上線時,經過幾次握手成功,將該使用者存入一個線上使用者緩衝器:UserCache。

②文字訊息都是通過伺服器轉寄的,使用者首先將文字訊息封裝成一個對象(這個對象包含文字訊息內容、來自哪裡ip、發送給誰ip等),發送到伺服器,伺服器再從線上使用者緩衝器中遍曆出要發送的對象ip,然後轉寄給該使用者,即完成轉寄,跟我的Android之高仿手機QQ聊天是類似的。

③檔案傳輸,是使用者之間單獨建立串連的,當一方要給另一方傳送檔案時,先通過伺服器轉寄該檔案大小、名稱等資訊,告知對方是否接收檔案,如果對方接收,即啟動一個監聽檔案傳書的Socket,然後再回饋該資訊(也是通過伺服器轉寄)給另一方,此時啟動一個線程Socket去串連對方傳送檔案(這中間,最好是加上逾時判斷,我這裡很簡單,就沒有處理)。另外需要注意的是,我這裡是通過SwingWorker來更新介面的,有點類似於Android的AsyncTask,做過Android的童鞋應該就很清楚了。


由於是代碼年代比較久遠,也難免會有些細節會忘記,所以詳細代碼我就不給大家分析了,其實是很簡單的,想學習一下的童鞋可以下載源碼參考一下,下面我們來看看重要的兩個部分代碼:

Server.java:

/** * 伺服器,接受使用者登入、離線 *  * @author way *  */public class Server {private ServerSocket serverSocket = null;private UserCache userCache = UserCache.getInstance();// 使用者緩衝器private Transffer transffer = new TransfferImpl();private boolean isStarted = true;public Server() {InetAddress address;try {address = InetAddress.getByName(Constants.SERVER_IP);serverSocket = new ServerSocket(Constants.SERVER_PORT, 0, address);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();System.exit(0);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();System.exit(0);}}public void start() {while (isStarted) {try {Socket socket = serverSocket.accept();TranObject object = transffer.get(socket);process(socket, object);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/** * 對來自使用者的請求進行處理 *  * @param socket * @param object */private void process(Socket socket, TranObject object) {LLogger.info("接收到使用者訊息!");switch (object.getType()) {case LOGIN:login(socket, object);break;case LOGOUT:logout(socket, object);break;}}/** * 登入,登入完成後要向所有線上使用者通報 * @param socket * @param object */private void login(Socket socket, TranObject object) {LLogger.info("使用者登入:" + object.getFromUser().getIp());userCache.add(object.getFromUser());TranObject<Set<User>> o = new TranObject<Set<User>>(TranObjectType.LOGIN);o.setToUser(object.getFromUser());o.setObject(userCache.get());try {transffer.tran(socket, o);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//需要向所有使用者發送該使用者登入訊息TranObject<User> loginO = new TranObject<User>(TranObjectType.LOGIN);loginO.setObject(object.getFromUser());broadcast(loginO);}/** * 離線,離線完成後要向所有線上使用者通報 * @param socket * @param object */private void logout(Socket socket, TranObject object) {LLogger.info("使用者離線:" + object.getFromUser().getIp());userCache.delete(object.getFromUser());//需要向所有使用者發送使用者離線訊息 TranObject<User> logoutO = new TranObject<User>(TranObjectType.LOGOUT);logoutO.setObject(object.getFromUser());broadcast(logoutO);}/** * 向所有線上使用者發送廣播包 *  * @param object */private void broadcast(TranObject object){Set<User> set = userCache.get();for(User u: set){object.setToUser(u);try {transffer.tranNoResponse(object);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public static void main(String[] args) {new Server().start();}}

下面是Client.java:

/** * 用戶端 * 需要啟動: * 1. 用戶端Message Service器監聽 * 2. 訊息處理器 * 3. 登入並顯示介面 *  * @author way * */public class Client {private User user = new User();private ClientSender sender = ClientSenderImpl.getInstance();private MessageProcessor messageProcessor = new MessageProcessor();//訊息處理器private ClientServer server;//訊息監聽器private MainFrame frame = new MainFrame(this);private Cache cache = Cache.getInstance();public Client(String name){user.setName(name);user.setPort(Constants.CLIENT_SERVER_PORT);String ip = "";try {ip = getIp();} catch (UnknownHostException e1) {e1.printStackTrace();}if(ip==null||ip.equals("")){JOptionPane.showMessageDialog(null,"擷取本機IP失敗! ");return;}user.setIp(ip);cache.setNowUser(user);if(!login()){JOptionPane.showMessageDialog(null,"無法與伺服器建立串連!");return;}/** * 啟動訊息處理器 */messageProcessor.execute();/** * 啟動伺服器 */try {server = new ClientServer(frame,ip);server.execute();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();JOptionPane.showMessageDialog(null, "連接埠已被佔用,程式退出!");System.exit(0);}//顯示主視窗 //AWTUtilities.setWindowOpacity(frame, 1f);frame.addWindowListener(new WindowListener(){@Overridepublic void windowOpened(WindowEvent e) {// TODO Auto-generated method stub}@Overridepublic void windowClosing(WindowEvent e) {}@Overridepublic void windowClosed(WindowEvent e) {// TODO Auto-generated method stubSystem.exit(0);}@Overridepublic void windowIconified(WindowEvent e) {// TODO Auto-generated method stub}@Overridepublic void windowDeiconified(WindowEvent e) {// TODO Auto-generated method stub}@Overridepublic void windowActivated(WindowEvent e) {// TODO Auto-generated method stub}@Overridepublic void windowDeactivated(WindowEvent e) {// TODO Auto-generated method stub}});frame.setVisible(true);}private String getIp() throws UnknownHostException{String ip = InetAddress.getLocalHost().getHostAddress();return ip;}/** * 退出操作 * @return */public void logout(){LLogger.info("使用者退出登入!");sender.logout();}/** * 登入  */private boolean login(){try {Set<User> userSet = null;userSet = sender.login();frame.getCenterPanel().addUser(userSet);return true;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}return false;}public static void main(String[] args){UIManager.put("swing.boldMetal", Boolean.FALSE);new Client("測試");}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.