初學Java,用到網絡編程和多線程的相關知識編輯了一套聊天程序,僅供參考,多多包涵:
這是服務器:
package test; import javax.swing.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; public class 服務器 { public static void main(String[] args) { 服務器 ff = new 服務器(); try { ff.WindowsChat(); } catch (IOException e) { } } CopyOnWriteArrayList<Socket> socket = new CopyOnWriteArrayList<>(); String a;int q; BufferedReader h; String c; Map<Socket,String>map=new HashMap<>(); Map<Socket,String>color=new HashMap<>(); public void WindowsChat() throws IOException { ServerSocket ss = new ServerSocket(Integer.parseInt(JOptionPane.showInputDialog(null, "請輸入羣聊密鑰", "666"))); String title; JFrame jf=new JFrame(); new Thread().start(); new Thread(() -> { Socket s; while (true) { try { s = ss.accept(); this.socket.add(s); this.h=new BufferedReader(new InputStreamReader(s.getInputStream())); String aaa= h.readLine(); String bbb=h.readLine(); var i = "#000000\r\n"+"(" + aaa+ ")連線 (" + socket.size() + "人)\r\n"; map.put(s, aaa); color.put(s, bbb); for (Socket y : socket) { try { PrintWriter ll = new PrintWriter(y.getOutputStream()); ll.println(i); ll.flush(); } catch (IOException e) { e.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } } }).start(); while (true) { this.q = socket.size(); for (Socket x : socket) { new Thread(() -> { while (true) { try { this.a = new BufferedReader(new InputStreamReader(x.getInputStream())).readLine() ; socket.forEach(y -> { try { PrintWriter pp = new PrintWriter(y.getOutputStream()); pp.println(color.get(x)+"\r\n"+a ); pp.flush(); } catch (IOException e) { e.printStackTrace(); } }); } catch (IOException e) { socket.remove(x); for (Socket y : socket) { try { PrintWriter ii = new PrintWriter(y.getOutputStream()); ii.println("#000000\r\n("+map.get(x)+")下線 (" + socket.size() + "人)\r\n"); ii.flush(); } catch (IOException ex) { }} // } Thread.currentThread().stop(); } } }).start(); } while (true) { if (socket.size() != q) break; } } }}
先開啓服務器,再開啓用戶端
下面是用戶端:
package test; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.DefaultCaret; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.Random; import java.util.Scanner; public class test22 extends JFrame implements KeyListener, ActionListener { public static void main(String[] args) { new test11().WindowsChat(); } Socket s; String name; BufferedReader bf; String c; JTextField text = new JTextField(); JButton search = new JButton("發送"); JTextPane t = new JTextPane(); Random rand = new Random(); public void WindowsChat() { try { String a = JOptionPane.showInputDialog(this, "請輸入對方ip", "192.168.3.209"); String b = JOptionPane.showInputDialog(this, "請輸入密鑰", "666"); this.s = new Socket(a, Integer.parseInt(b)); } catch (IOException ex) { JOptionPane.showMessageDialog(null, "錯誤", "提示", JOptionPane.ERROR_MESSAGE); return; } this.name = JOptionPane.showInputDialog(null, "登錄成功!請輸入你的暱稱", "傻狗" + rand.nextInt(100) + "號"); Object[]colors={"red#FF0000","black#000000","blue#0000FF","purple#800080","green#008000","orange#FFA500","pink#FFC0CB","yellow#FFFF00"}; this.c= JOptionPane.showInputDialog(null, "請輸入你的字體顏色", "登錄成功!",-1,null, colors, colors[1]).toString(); String cc=c.substring(c.lastIndexOf("#")); try { PrintWriter po = new PrintWriter(s.getOutputStream()); po.println(name+"\r\n"+cc); po.flush(); } catch (IOException e) { e.printStackTrace(); } setVisible(true); setTitle("聊天系統(" + name + ")"); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setLocationRelativeTo(null); setSize(600, 750); setResizable(false); setLayout(null); text.setBounds(10, 10, 510, 80); search.setBounds(525, 10, 65, 80); t.setFont(new Font("楷體", Font.BOLD, 20)); t.setBounds(10, 100, 570, 600); t.setFocusable(false);//DefaultCaret caret = (DefaultCaret)this.t.getCaret(); // caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); add(text); add(search); add(t); search.addActionListener(this); new Thread(() -> { while (true) { try {this.bf=new BufferedReader(new InputStreamReader(s.getInputStream())); String color=bf.readLine(); t.setForeground(Color.decode(color)); t.replaceSelection(bf.readLine() + "\r\n"); } catch (IOException e) { JOptionPane.showMessageDialog(null, "服務器斷線!"); System.exit(0); } } }).start(); new Thread(() -> { text.addKeyListener(this); }).start(); } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER&&!text.getText().equals("")) { try { PrintWriter pw = new PrintWriter(s.getOutputStream()); pw.println(name + ": " + text.getText() + "\r\n"); pw.flush(); text.setText(""); } catch (IOException ex) { ex.printStackTrace(); } } } @Override public void keyReleased(KeyEvent e) { } @Override public void actionPerformed(ActionEvent e) { if (!text.getText().equals("")){ try { PrintWriter pw = new PrintWriter(s.getOutputStream()); pw.println(name + ": " + text.getText() + "\r\n"); pw.flush(); text.setText(""); } catch (IOException ex) { ex.printStackTrace(); } }} }