怎么在java中利用C/S模式實現聊天程序?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
監聽線程:建立服務器的套接字,接收來自客戶端的連接,每當有客戶端連接到服務器時,服務器都要把該客戶端的套接字添加到變長數組socketsss中,并且要給每個用戶都創建單獨的線程。
消息處理線程:在輸入流中讀取來自客戶端的UTF字符串,然后遍歷Vector數組socketsss,將UTF字符串寫入到對每一個用戶的輸出流中。
服務器的功能就是這些了,這樣就能實現基本的聊天室功能了,感覺最難的地方就是消息轉發了,不過最后找到了合適的方法也解決了。只有當自己動手去寫了才會發現自己有什么地方的不足,比如,設置關閉按鈕的響應時,在彈出的對話框中點什么都關閉,后來發現是前面窗體設置關閉沒有改成無操作;還有就是剛開始服務器只能接收處理一組消息,第二組就出問題了,是因為我以為把監聽寫到線程中就可以無限調用了,還是要把他放到循環中去??傊?,紙上得來終覺淺絕知此事要躬行,凡事動手去做比看書理解要深刻,學編程還是要多動動手。
界面展示:
package server; import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import java.awt.event.*; import javax.swing.*; public class Server extends JFrame { JTextArea textShow; JButton start; Vector socketsss = new Vector();//這里用到了變長對象數組,用來存儲來自客戶端的socket對象 ServerSocket server = null; Socket clients; Server() { // 服務器的構造函數,并且初始化 init(); setVisible(true); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); setBounds(450, 150, 340, 455); setTitle("好好學習天天向上聊天室服務器"); setResizable(false); } void init() { // 設置布局和事件監視器 setLayout(new FlowLayout()); getContentPane().setBackground(new Color(20, 85, 237)); textShow = new JTextArea(21, 29); textShow.setBackground(new Color(45, 210, 209)); start = new JButton(" 啟動服務器 "); start.setBackground(new Color(236, 134, 21)); add(start); add(new JScrollPane(textShow)); textShow.setEditable(false); start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //在這里啟動監聽的線程 Listen listen = new Listen(); Thread go = new Thread(listen); go.start(); } }); addWindowListener(new WindowAdapter() { // 響應關閉按鈕功能 public void windowClosing(WindowEvent e) { int option = JOptionPane .showConfirmDialog(null, "親愛的你真的要離開聊天室么?", " 好好學習天天向上聊天室", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (option == JOptionPane.YES_OPTION) System.exit(0); } }); } // init()結束 class ServerThread extends Thread { // 服務器消息處理的線程 Socket socket; DataOutputStream out = null; DataInputStream in = null; String s = null; Vector sockets = new Vector(); int j = 0; ServerThread(Socket t, Vector socketss) { socket = t; sockets = socketss; try { in = new DataInputStream(socket.getInputStream()); } catch (IOException e) { } } public void run() { while (true) { try { String r = in.readUTF();// 堵塞狀態,除非讀取到信息 for (int j = 0; j < sockets.size(); j++) { out = new DataOutputStream( ((Socket) sockets.get(j)).getOutputStream()); // 對于每個數組內的socket對象都建立輸出流 out.writeUTF(r); } } catch (IOException e) { textShow.append("有一個逗比離開了\n"); return; } } } } class Listen implements Runnable { // 服務器監聽線程 ServerSocket server; Socket clients; public void run() { while (true) { try { server = new ServerSocket(8888); textShow.append(new java.text.SimpleDateFormat( "yy-MM-dd HH:mm:ss").format(new Date()) + "服務器已開啟\n"); } catch (IOException e1) { textShow.append("正在監聽\n"); // ServerSocket對象不能重復創建 } try { textShow.append(new java.text.SimpleDateFormat( "yy-MM-dd HH:mm:ss").format(new Date()) + " 等待用戶連接......\n"); clients = server.accept(); socketsss.add(clients); ServerThread handlers = new ServerThread(clients, socketsss); handlers.start(); // 為每個用戶創建單獨的消息處理線程 textShow.append(new java.text.SimpleDateFormat( "yy-MM-dd HH:mm:ss").format(new Date()) + "有用戶連接,用戶的地址:" + clients.getInetAddress() + "\n"); } catch (IOException e1) { textShow.append(new java.text.SimpleDateFormat( "yy-MM-dd HH:mm:ss").format(new Date()) + "正在等待逗比來臨......\n"); } } } } public static void main(String args[]) { Server server = new Server(); } }
看完上述內容,你們掌握怎么在java中利用C/S模式實現聊天程序的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。