一个简单C/S聊天程序

Posted sqjs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一个简单C/S聊天程序相关的知识,希望对你有一定的参考价值。

服务器界面:

技术分享图片

客户端登录界面:

技术分享图片

客户端界面:

技术分享图片

使用的是java里面的socket接口进行服务器与客户端之间的通信

具体代码:

login.java:

  1 /*
  2  * To change this license header, choose License Headers in Project Properties.
  3  * To change this template file, choose Tools | Templates
  4  * and open the template in the editor.
  5  */
  6 package program;
  7 
  8 import com.mysql.jdbc.Connection;
  9 import com.mysql.jdbc.Statement;
 10 import java.awt.Toolkit;
 11 import java.sql.DriverManager;
 12 import java.sql.ResultSet;
 13 import java.sql.SQLException;
 14 import java.util.logging.Level;
 15 import java.util.logging.Logger;
 16 import javax.swing.JOptionPane;
 17 
 18 /**
 19  *
 20  * @author 杉琪建
 21  */
 22 public class login extends javax.swing.JFrame {
 23 
 24     /**
 25      * Creates new form login
 26      */
 27     public login() {
 28         initComponents();//登录界面UI的设计函数
 29         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;
 30         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;
 31         this.setLocation((screen_width - this.getWidth()) / 2,
 32                 (screen_height - this.getHeight()) / 2);//设置窗口弹出为桌面正中央
 33     }
 34 
 35     /**
 36      * This method is called from within the constructor to initialize the form.
 37      * WARNING: Do NOT modify this code. The content of this method is always
 38      * regenerated by the Form Editor.
 39      */
 40     @SuppressWarnings("unchecked")
 41     // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
 42     private void initComponents() {
 43         bindingGroup = new org.jdesktop.beansbinding.BindingGroup();
 44 
 45         jTextField1 = new javax.swing.JTextField();
 46         jPasswordField1 = new javax.swing.JPasswordField();
 47         jLabel1 = new javax.swing.JLabel();
 48         jLabel2 = new javax.swing.JLabel();
 49         jButton1 = new javax.swing.JButton();
 50 
 51         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
 52 
 53         org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("登录界面"), this, org.jdesktop.beansbinding.BeanProperty.create("title"));
 54         bindingGroup.addBinding(binding);
 55 
 56         jPasswordField1.addActionListener(new java.awt.event.ActionListener() {
 57             public void actionPerformed(java.awt.event.ActionEvent evt) {
 58                 jPasswordField1ActionPerformed(evt);
 59             }
 60         });
 61 
 62         jLabel1.setText("用户名:");
 63 
 64         jLabel2.setText("密码:");
 65 
 66         jButton1.setText("登录");
 67         jButton1.addActionListener(new java.awt.event.ActionListener() {
 68             public void actionPerformed(java.awt.event.ActionEvent evt) {
 69                 jButton1ActionPerformed(evt);
 70             }
 71         });
 72 
 73         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
 74         getContentPane().setLayout(layout);
 75         layout.setHorizontalGroup(
 76             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 77             .addGroup(layout.createSequentialGroup()
 78                 .addContainerGap(39, Short.MAX_VALUE)
 79                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 80                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 81                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 82                             .addComponent(jLabel1)
 83                             .addComponent(jLabel2))
 84                         .addGap(27, 27, 27)
 85                         .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
 86                             .addComponent(jPasswordField1, javax.swing.GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE)
 87                             .addComponent(jTextField1))
 88                         .addGap(101, 101, 101))
 89                     .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
 90                         .addComponent(jButton1)
 91                         .addGap(31, 31, 31))))
 92         );
 93         layout.setVerticalGroup(
 94             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 95             .addGroup(layout.createSequentialGroup()
 96                 .addGap(31, 31, 31)
 97                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
 98                     .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
 99                     .addComponent(jLabel1))
100                 .addGap(18, 18, 18)
101                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
102                     .addComponent(jPasswordField1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
103                     .addComponent(jLabel2))
104                 .addGap(18, 18, 18)
105                 .addComponent(jButton1)
106                 .addContainerGap(16, Short.MAX_VALUE))
107         );
108 
109         bindingGroup.bind();
110 
111         pack();
112     }// </editor-fold>                        
113 
114     private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
115         load();
116     }                                        
117 
118     private void jPasswordField1ActionPerformed(java.awt.event.ActionEvent evt) {                                                
119         load();
120     }                                               
121 
122     public void load() {//登录判断跳转函数
123         this.setVisible(false);
124         String userName = jTextField1.getText().trim();//接受用户名
125         String passwd = new String(jPasswordField1.getPassword());//接受密码
126         try {
127             DriverManager.registerDriver(new com.mysql.jdbc.Driver());
128             String dbURL = "jdbc:mysql://127.0.0.1:3306/test";
129             Connection connection = (Connection) DriverManager.getConnection(dbURL, "root", "1239842619");//进行数据库的连接
130             Statement statement = (Statement) connection.createStatement();
131             String sql = "select * from clients where (name=‘" + userName + "‘ and passwd=‘" + passwd + "‘)";//简单的查询是否有相应的数据在数据库里面
132             ResultSet rs = statement.executeQuery(sql);
133             if (rs.next()) {
134                 new Client(userName).setVisible(true);
135             } else {
136                 JOptionPane.showMessageDialog(null, "用户名不存在或密码错误", "登录失败", JOptionPane.ERROR_MESSAGE);
137                 System.exit(0);
138             }
139         } catch (SQLException ex) {
140             Logger.getLogger(login.class.getName()).log(Level.SEVERE, null, ex);
141         }
142     }
143 
144     /**
145      * @param args the command line arguments
146      */
147     public static void main(String args[]) {
148         /* Set the Nimbus look and feel */
149         //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
150         /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
151          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
152          */
153         try {
154             for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
155                 if ("Nimbus".equals(info.getName())) {
156                     javax.swing.UIManager.setLookAndFeel(info.getClassName());
157                     break;
158                 }
159             }
160         } catch (ClassNotFoundException ex) {
161             java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
162         } catch (InstantiationException ex) {
163             java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
164         } catch (IllegalAccessException ex) {
165             java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
166         } catch (javax.swing.UnsupportedLookAndFeelException ex) {
167             java.util.logging.Logger.getLogger(login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
168         }
169         //</editor-fold>
170         //</editor-fold>
171         //</editor-fold>
172         //</editor-fold>
173 
174         /* Create and display the form */
175         java.awt.EventQueue.invokeLater(new Runnable() {
176             public void run() {
177                 new login().setVisible(true);
178             }
179         });
180     }
181 
182     // Variables declaration - do not modify                     
183     private javax.swing.JButton jButton1;
184     private javax.swing.JLabel jLabel1;
185     private javax.swing.JLabel jLabel2;
186     private javax.swing.JPasswordField jPasswordField1;
187     private javax.swing.JTextField jTextField1;
188     private org.jdesktop.beansbinding.BindingGroup bindingGroup;
189     // End of variables declaration                   
190 }

Client.java:

  1 /*
  2  * To change this license header, choose License Headers in Project Properties.
  3  * To change this template file, choose Tools | Templates
  4  * and open the template in the editor.
  5  */
  6 package program;
  7 
  8 import java.awt.Toolkit;
  9 import java.io.BufferedReader;
 10 import java.io.InputStreamReader;
 11 import java.io.PrintWriter;
 12 import java.net.Socket;
 13 
 14 /**
 15  *
 16  * @author 杉琪建
 17  */
 18 public class Client extends javax.swing.JFrame {
 19     Socket socket;
 20     PrintWriter writer;
 21     BufferedReader reader;
 22     MessageThread messageThread;
 23     String sourceName;
 24     /**
 25      * Creates new form Server
 26      */
 27     public Client(String userName) {
 28         initComponents();
 29         sourceName = userName;//接受登录界面的输入名字作为客户端进程的名字
 30         setTitle(userName);
 31         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
 32         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
 33         this.setLocation((screen_width - this.getWidth()) / 2,  
 34                 (screen_height - this.getHeight()) / 2);
 35         try {
 36             socket = new Socket("127.0.0.1", 4705);//默认设置为本机方便测试
 37             reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 38             writer = new PrintWriter(socket.getOutputStream());
 39             String message = userName;
 40             sendMessage(message);//在初始化程序的同时发送一条消息到服务器,告知自己的名字
 41             messageThread = new MessageThread(reader);
 42             messageThread.start();
 43         } catch (Exception e) {
 44             System.out.println("Error : " + e);
 45         }
 46         
 47     }
 48 
 49     /**
 50      * This method is called from within the constructor to initialize the form.
 51      * WARNING: Do NOT modify this code. The content of this method is always
 52      * regenerated by the Form Editor.
 53      */
 54     @SuppressWarnings("unchecked")
 55     // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
 56     private void initComponents() {
 57         bindingGroup = new org.jdesktop.beansbinding.BindingGroup();
 58 
 59         jPanel1 = new javax.swing.JPanel();
 60         jLabel1 = new javax.swing.JLabel();
 61         jScrollPane1 = new javax.swing.JScrollPane();
 62         jList1 = new javax.swing.JList<>();
 63         jScrollPane2 = new javax.swing.JScrollPane();
 64         jTextArea1 = new javax.swing.JTextArea();
 65         jTextField1 = new javax.swing.JTextField();
 66         jButton1 = new javax.swing.JButton();
 67 
 68         setTitle(getTitle());
 69 
 70         org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${name}"), this, org.jdesktop.beansbinding.BeanProperty.create("title"));
 71         bindingGroup.addBinding(binding);
 72 
 73         addWindowListener(new java.awt.event.WindowAdapter() {
 74             public void windowClosing(java.awt.event.WindowEvent evt) {
 75                 formWindowClosing(evt);
 76             }
 77         });
 78 
 79         jLabel1.setText("成员列表");
 80 
 81         jList1.setModel(new javax.swing.AbstractListModel<String>() {
 82             String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
 83             public int getSize() { return strings.length; }
 84             public String getElementAt(int i) { return strings[i]; }
 85         });
 86         jList1.addMouseListener(new java.awt.event.MouseAdapter() {
 87             public void mouseClicked(java.awt.event.MouseEvent evt) {
 88                 jList1MouseClicked(evt);
 89             }
 90         });
 91         jScrollPane1.setViewportView(jList1);
 92 
 93         javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
 94         jPanel1.setLayout(jPanel1Layout);
 95         jPanel1Layout.setHorizontalGroup(
 96             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 97             .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE)
 98             .addGroup(jPanel1Layout.createSequentialGroup()
 99                 .addComponent(jScrollPane1)
100                 .addContainerGap())
101         );
102         jPanel1Layout.setVerticalGroup(
103             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
104             .addGroup(jPanel1Layout.createSequentialGroup()
105                 .addGap(11, 11, 11)
106                 .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)
107                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
108                 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE))
109         );
110 
111         jTextArea1.setEditable(false);
112         jTextArea1.setColumns(20);
113         jTextArea1.setRows(5);
114         jScrollPane2.setViewportView(jTextArea1);
115 
116         jTextField1.addActionListener(new java.awt.event.ActionListener() {
117             public void actionPerformed(java.awt.event.ActionEvent evt) {
118                 jTextField1ActionPerformed(evt);
119             }
120         });
121 
122         jButton1.setText("发送");
123         jButton1.addActionListener(new java.awt.event.ActionListener() {
124             public void actionPerformed(java.awt.event.ActionEvent evt) {
125                 jButton1ActionPerformed(evt);
126             }
127         });
128 
129         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
130         getContentPane().setLayout(layout);
131         layout.setHorizontalGroup(
132             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
133             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
134                 .addContainerGap()
135                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
136                     .addComponent(jTextField1)
137                     .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE))
138                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
139                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
140                     .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
141                     .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)))
142         );
143         layout.setVerticalGroup(
144             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
145             .addGroup(layout.createSequentialGroup()
146                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
147                     .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
148                         .addContainerGap()
149                         .addComponent(jScrollPane2))
150                     .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
151                 .addGap(18, 18, 18)
152                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
153                     .addComponent(jTextField1)
154                     .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE))
155                 .addContainerGap())
156         );
157 
158         bindingGroup.bind();
159 
160         pack();
161     }// </editor-fold>                        
162 
163     private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
164         send();
165     }                                        
166 
167     private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
168         send();
169     }                                           
170 
171     private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
172         String message = "用户已经下线";
173         sendMessage(message);
174     }                                  
175 
176     private void jList1MouseClicked(java.awt.event.MouseEvent evt) {                                    
177         send_2();
178     }                                   
179 
180     /**
181      * @param args the command line arguments
182      */
183     public static void main(String args[]) {
184         /* Set the Nimbus look and feel */
185         //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
186         /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
187          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
188          */
189         try {
190             for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
191                 if ("Nimbus".equals(info.getName())) {
192                     javax.swing.UIManager.setLookAndFeel(info.getClassName());
193                     break;
194                 }
195             }
196         } catch (ClassNotFoundException ex) {
197             java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
198         } catch (InstantiationException ex) {
199             java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
200         } catch (IllegalAccessException ex) {
201             java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
202         } catch (javax.swing.UnsupportedLookAndFeelException ex) {
203             java.util.logging.Logger.getLogger(Client.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
204         }
205         //</editor-fold>
206         //</editor-fold>
207         //</editor-fold>
208         //</editor-fold>
209 
210         /* Create and display the form */
211         java.awt.EventQueue.invokeLater(new Runnable() {
212             public void run() {
213                 new Client("新用户").setVisible(true);
214             }
215         });
216     }
217     public void send() {//发送文本输入区域的文字到服务器进行群聊
218         String message = jTextField1.getText().trim();
219         jTextField1.setText(null);
220         if(message.equals("") || message == null) return ;
221         sendMessage(message);
222     }
223     
224     public void send_2(){//发送文本输入区域的文字到服务器进行私聊
225         String choosedName=(String)this.jList1.getSelectedValue();
226         String message = jTextField1.getText().trim();
227         jTextField1.setText(null);
228         String temp_message = "to " + choosedName + ":" + message + "\\r\\n";
229         jTextArea1.append(temp_message);
230         if(message.equals("") || message == null) return ;
231         message = "|" + choosedName + "!" + sourceName + ":" + message;
232         sendMessage(message);
233     }
234     
235     public void sendMessage(String message) {//群发服务器消息
236         writer.println(message);
237         writer.flush();
238     }
239     
240     class MessageThread  extends Thread{
241         BufferedReader reader;
242         
243         public MessageThread(BufferedReader reader) {
244             this.reader = reader;
245         }
246         
247         @Override
248         public void run() {
249             String message = null;
250             while(true){//死循环等待接受信息的发送
251                 try {
252                     message = reader.readLine();
253                     if(message != null && message != ""){
254                         if(message.charAt(0) == ‘[‘){//判别接受到的消息是否是服务器发来的用户列表更新的消息
255                             String[] list = message.split(", ");
256                             list[0] = list[0].substring(1);
257                             list[list.length-1] = list[list.length-1].substring(0, list[list.length-1].length()-1);
258                             jList1.setListData(list);
259                         }
260                         else{
261                             message = message + "\\r\\n";
262                             jTextArea1.append(message);
263                         }
264                     }
265                 } catch (Exception e) {
266                     System.out.println("Error : " + e);
267                 }
268             }
269         }
270     
271     }
272     
273 
274     // Variables declaration - do not modify                     
275     private javax.swing.JButton jButton1;
276     private javax.swing.JLabel jLabel1;
277     private javax.swing.JList<String> jList1;
278     private javax.swing.JPanel jPanel1;
279     private javax.swing.JScrollPane jScrollPane1;
280     private javax.swing.JScrollPane jScrollPane2;
281     private javax.swing.JTextArea jTextArea1;
282     private javax.swing.JTextField jTextField1;
283     private org.jdesktop.beansbinding.BindingGroup bindingGroup;
284     // End of variables declaration                   
285 }

Server.java:

  1 /*
  2  * To change this license header, choose License Headers in Project Properties.
  3  * To change this template file, choose Tools | Templates
  4  * and open the template in the editor.
  5  */
  6 package program;
  7 
  8 import java.awt.Toolkit;
  9 import java.io.BufferedReader;
 10 import java.io.InputStreamReader;
 11 import java.io.PrintWriter;
 12 import java.net.ServerSocket;
 13 import java.net.Socket;
 14 import java.util.ArrayList;
 15 import java.util.Vector;
 16 
 17 /**
 18  *
 19  * @author 杉琪建
 20  */
 21 public class Server extends javax.swing.JFrame {
 22     ServerSocket serverSocket;
 23     ServerThread serverThread;
 24     ArrayList<ClientThread> clients;//客户线程数组
 25     Vector<String> Names = new Vector<String>();//用户列表
 26     /**
 27      * Creates new form Server
 28      */
 29     public Server() {
 30         initComponents();
 31         jList1.setListData(Names);
 32         int screen_width = Toolkit.getDefaultToolkit().getScreenSize().width;  
 33         int screen_height = Toolkit.getDefaultToolkit().getScreenSize().height;  
 34         this.setLocation((screen_width - this.getWidth()) / 2,  
 35                 (screen_height - this.getHeight()) / 2);
 36         try {
 37             clients = new ArrayList<ClientThread>();
 38             serverSocket = new ServerSocket(4705);
 39             serverThread = new ServerThread(serverSocket);
 40             serverThread.start();
 41         } catch (Exception e) {
 42             System.out.println("Error : " + e);
 43         }
 44     }
 45 
 46     /**
 47      * This method is called from within the constructor to initialize the form.
 48      * WARNING: Do NOT modify this code. The content of this method is always
 49      * regenerated by the Form Editor.
 50      */
 51     @SuppressWarnings("unchecked")
 52    
 53     // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
 54     private void initComponents() {
 55         bindingGroup = new org.jdesktop.beansbinding.BindingGroup();
 56 
 57         jPanel1 = new javax.swing.JPanel();
 58         jScrollPane1 = new javax.swing.JScrollPane();
 59         jTextArea1 = new javax.swing.JTextArea();
 60         jLabel1 = new javax.swing.JLabel();
 61         jScrollPane2 = new javax.swing.JScrollPane();
 62         jList1 = new javax.swing.JList<>();
 63         jScrollBar1 = new javax.swing.JScrollBar();
 64         jTextField1 = new javax.swing.JTextField();
 65         jButton1 = new javax.swing.JButton();
 66 
 67         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
 68 
 69         org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("服务器端"), this, org.jdesktop.beansbinding.BeanProperty.create("title"));
 70         bindingGroup.addBinding(binding);
 71 
 72         jTextArea1.setEditable(false);
 73         jTextArea1.setColumns(20);
 74         jTextArea1.setRows(5);
 75         jScrollPane1.setViewportView(jTextArea1);
 76 
 77         jLabel1.setText("成员列表");
 78 
 79         jList1.setModel(jList1.getModel());
 80         jScrollPane2.setViewportView(jList1);
 81 
 82         javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
 83         jPanel1.setLayout(jPanel1Layout);
 84         jPanel1Layout.setHorizontalGroup(
 85             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 86             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
 87                 .addContainerGap()
 88                 .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE)
 89                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
 90                 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 91                     .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
 92                     .addGroup(jPanel1Layout.createSequentialGroup()
 93                         .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)
 94                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 95                         .addComponent(jScrollBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
 96                 .addContainerGap())
 97         );
 98         jPanel1Layout.setVerticalGroup(
 99             jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
100             .addGroup(jPanel1Layout.createSequentialGroup()
101                 .addContainerGap()
102                 .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
103                     .addComponent(jScrollPane1)
104                     .addGroup(jPanel1Layout.createSequentialGroup()
105                         .addComponent(jLabel1)
106                         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
107                         .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
108                             .addComponent(jScrollBar1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
109                             .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE))))
110                 .addContainerGap())
111         );
112 
113         jTextField1.addActionListener(new java.awt.event.ActionListener() {
114             public void actionPerformed(java.awt.event.ActionEvent evt) {
115                 jTextField1ActionPerformed(evt);
116             }
117         });
118 
119         jButton1.setText("发送");
120         jButton1.addActionListener(new java.awt.event.ActionListener() {
121             public void actionPerformed(java.awt.event.ActionEvent evt) {
122                 jButton1ActionPerformed(evt);
123             }
124         });
125 
126         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
127         getContentPane().setLayout(layout);
128         layout.setHorizontalGroup(
129             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
130             .addGroup(layout.createSequentialGroup()
131                 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
132                 .addGap(0, 0, Short.MAX_VALUE))
133             .addGroup(layout.createSequentialGroup()
134                 .addContainerGap()
135                 .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 432, javax.swing.GroupLayout.PREFERRED_SIZE)
136                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
137                 .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
138                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
139         );
140         layout.setVerticalGroup(
141             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
142             .addGroup(layout.createSequentialGroup()
143                 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
144                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
145                 .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
146                     .addComponent(jTextField1)
147                     .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, 49, Short.MAX_VALUE))
148                 .addContainerGap())
149         );
150 
151         bindingGroup.bind();
152 
153         pack();
154     }// </editor-fold>                        
155 
156     private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
157         // TODO add your handling code here:
158         send();
159     }                                        
160 
161     private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
162         // TODO add your handling code here:
163         send();
164     }                                           
165 
166     /**
167      * @param args the command line arguments
168      */
169     public static void main(String args[]) {
170         /* Set the Nimbus look and feel */
171         //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
172         /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
173          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
174          */
175         try {
176             for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
177                 if ("Nimbus".equals(info.getName())) {
178                     javax.swing.UIManager.setLookAndFeel(info.getClassName());
179                     break;
180                 }
181             }
182         } catch (ClassNotFoundException ex) {
183             java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
184         } catch (InstantiationException ex) {
185             java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
186         } catch (IllegalAccessException ex) {
187             java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
188         } catch (javax.swing.UnsupportedLookAndFeelException ex) {
189             java.util.logging.Logger.getLogger(Server.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
190         }
191         //</editor-fold>
192         //</editor-fold>
193         //</editor-fold>
194         //</editor-fold>
195 
196         /* Create and display the form */
197         java.awt.EventQueue.invokeLater(new Runnable() {
198             public void run() {
199                 new Server().setVisible(true);
200             }
201         });
202     }
203     
204     
205     class ClientThread extends Thread{
206         Socket socket;
207         BufferedReader reader;
208         PrintWriter writer;
209         int num;
210         /**
211          * 
212          * @param socket 连接的端口
213          * @param num 客户号码
214          */
215         public ClientThread(Socket socket, int num) {
216             try {
217                 this.socket = socket;
218                 this.num = num;
219                 reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
220                 writer = new PrintWriter(socket.getOutputStream());
221                 String inf = reader.readLine();
222                 sendMessage(inf + "已经上线");
223                 Names.add(inf);
224             } catch (Exception e) {
225                 System.out.println("Error : " + e);
226             }
227         }
228         
229         @Override
230         public void run() {
231             String message = null;
232             while(true) {
233                 try {
234                     message = reader.readLine();
235                     if(message.charAt(0) == ‘|‘){//识别是否是客户端发送的私聊信息
236                         message = message.substring(1, message.length());
237                         String[] list = message.split("!");
238                         send_2(list[0], list[1]);
239                     }
240                     else{
241                         String message1 = Names.get(this.num-1) + ":" + message;
242                         sendMessage(message1);
243                         if(message.equals("用户已经下线")){
244                             reader.close();
245                             writer.close();
246                             socket.close();
247                             ClientThread temp = clients.get(num - 1);
248                             Names.remove(num-1);
249                             UpdatejList1();
250                             clients.remove(num - 1);
251                             temp.stop();
252                             return ;
253                         }
254                     }
255                     
256                 } catch (Exception e) {
257                     System.out.println("Error1 : " + e);
258                 }
259             }
260         }
261     }
262     
263     class ServerThread extends Thread{//服务器线程
264         ServerSocket serverSocket;
265         public ServerThread(ServerSocket serverSocket) {
266             this.serverSocket = serverSocket;
267         }
268         @Override
269         public void run() {
270             int num = 1;
271             while(true) {//死循环等待新客户端的连接
272                 try {
273                     Socket socket = serverSocket.accept();
274                     ClientThread client = new ClientThread(socket, num++);
275                     client.start();
276                     clients.add(client);
277                     UpdatejList1();
278                     } catch (Exception e) {
279                     System.out.println("Error :" + e);
280                 }
281             }
282         }
283     }
284     
285     public void send() {//发送文本框中的消息
286         String message = jTextField1.getText().trim();
287         message = "服务器 :" + message;
288         jTextArea1.append(message + "\\r\\n");
289         jTextField1.setText(null);
290         sendServerMessage(message);// 群发服务器消息 
291     }
292     
293     public void send_2(String name, String message){
294         for(int i = 0; i <clients.size(); i++){
295             if(Names.get(i).equals(name)){
296                 clients.get(i).writer.println(message);
297                 clients.get(i).writer.flush();
298             }
299         }
300     }
301     /**
302      * 
303      * @param message 要发送的消息
304      */
305     public void sendMessage(String message) {//发送message消息
306         jTextArea1.append(message + "\\r\\n");
307         sendServerMessage(message);// 群发服务器消息 
308     }    
309     public void sendServerMessage(String message) {//发送服务器信息
310         //message =message + "\\r\\n";
311         for(int i = 0; i < clients.size(); i++) {
312             clients.get(i).writer.println(message);
313             clients.get(i).writer.flush();
314         }
315     }
316     public void UpdatejList1(){//更新所有客户端的用户列表
317         jList1.setListData(Names);
318         for(int i = 0; i < clients.size(); i++) {
319             clients.get(i).writer.println(Names);
320             clients.get(i).writer.flush();
321         }
322     }
323 
324     // Variables declaration - do not modify                     
325     private javax.swing.JButton jButton1;
326     private javax.swing.JLabel jLabel1;
327     private javax.swing.JList<String> jList1;
328     private javax.swing.JPanel jPanel1;
329     private javax.swing.JScrollBar jScrollBar1;
330     private javax.swing.JScrollPane jScrollPane1;
331     private javax.swing.JScrollPane jScrollPane2;
332     private javax.swing.JTextArea jTextArea1;
333     private javax.swing.JTextField jTextField1;
334     private org.jdesktop.beansbinding.BindingGroup bindingGroup;
335     // End of variables declaration                   
336 }

 

以上是关于一个简单C/S聊天程序的主要内容,如果未能解决你的问题,请参考以下文章

简单的方法来分享/讨论/协作的代码片段?

Java案例:基于TCP的简单聊天程序

C#实现多人视频聊天

Android:在视图/活动/片段之间滑动切换

Java NIO实现的C/S模式多人聊天工具

GitLab