一对多聊天系统
一對多聊天系統
在上一篇博客中,我們寫了一個基于TCP的客戶端和服務器的一對一雙向聊天系統,但只能開一個客戶端與服務器通信,我們在之前的代碼做一些改動,就實現了多個客戶端與服務器通信的系統,且服務器能向所有客戶端發送廣播!
代碼示例
創建服務器
import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; 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.ArrayList;import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField;public class Server extends JFrame implements ActionListener {PrintWriter pw;BufferedReader br;JTextArea jta;JTextField jtf;JButton jb;JPanel jp;JScrollPane jsp;ArrayList<Socket> sockets;ServerSocket ss;public static void main(String[] args) {new Server();}public Server() {jta = new JTextArea();jsp = new JScrollPane(jta);jtf = new JTextField(15);jb = new JButton("發送");jb.addActionListener(this);jp = new JPanel();jp.add(jtf);jp.add(jb);this.add(jsp, BorderLayout.CENTER);this.add(jp, BorderLayout.SOUTH);this.setSize(300, 200);this.setTitle("服務器");this.setVisible(true);new Thread(new Runnable() {@Overridepublic void run() {try {ss = new ServerSocket(10000);//存放客戶端連接來的Socketsockets = new ArrayList<>();while (true) {Socket socket = ss.accept();sockets.add(socket);jta.append("客戶端已成功連接服務器\n");Thread t = new Thread(new GetClientToServerMessage(Server.this, socket));t.start();}} catch (IOException e) {e.printStackTrace();}}}).start();}@Overridepublic void actionPerformed(ActionEvent e) {// 發送try {String str = jtf.getText();for (Socket socket : sockets) {pw = new PrintWriter(socket.getOutputStream(), true);pw.println(str);pw.flush();}jta.append("服務器廣播:" + str + "\n");jtf.setText("");} catch (IOException e1) {e1.printStackTrace();}}public void read(Socket socket) {try {while (true) {br = new BufferedReader(new InputStreamReader(socket.getInputStream()));jta.append(br.readLine() + "\n");}} catch (IOException e) {e.printStackTrace();}} }創建服務器接收客戶端消息的線程類
import java.net.Socket;public class GetClientToServerMessage implements Runnable {private Server server;private Socket socket;public GetClientToServerMessage(Server server,Socket socket) {this.server = server;this.socket = socket;}@Overridepublic void run() { server.read(socket);} }創建Client類
import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException;import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField;public class Client extends JFrame implements ActionListener {Socket s;PrintWriter pw;BufferedReader br;JTextArea jta;JTextField jtf;JButton jb;JPanel jp;JScrollPane jsp;JOptionPane jop;String username;public static void main(String[] args) {new Client();}public Client() {jta = new JTextArea();jsp = new JScrollPane(jta);jtf = new JTextField(15);jb = new JButton("發送");jb.addActionListener(this);jp = new JPanel();jp.add(jtf);jp.add(jb);this.add(jsp, BorderLayout.CENTER);this.add(jp, BorderLayout.SOUTH);this.setSize(300, 200);username = JOptionPane.showInputDialog("請輸入用戶名"); this.setTitle("客戶端"+username);this.setVisible(true);try {s = new Socket("127.0.0.1", 10000);jta.append("您已成功連接服務器\n");Thread t = new Thread(new GetServerToClientMessage(Client.this));t.start();} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void actionPerformed(ActionEvent e) {try {pw = new PrintWriter(s.getOutputStream(), true);String str = jtf.getText();jta.append(username+"說:" + str + "\n");pw.println(username+"說:"+str);pw.flush();jtf.setText("");} catch (IOException e1) {e1.printStackTrace();}}public void read(){try {while (true) {br = new BufferedReader(new InputStreamReader(s.getInputStream()));jta.append("服務器回復說:" + br.readLine()+ "\n");}} catch (IOException e) {e.printStackTrace();}} }創建接收服務器消息的線程類
public class GetServerToClientMessage implements Runnable {private Client client;public GetServerToClientMessage(Client client) {this.client = client;}@Overridepublic void run() {client.read();} }運行結果
總結
- 上一篇: Ubuntu下连上网络开始学习啦
- 下一篇: fullpage实例