发布时间:2025-12-09 11:53:01 浏览次数:1
做一个简易的聊天窗口程序,实现多人登录在线聊天功能。没有数据库的导入,等后期学习更多知识之后,再进行优化。
Server.java(服务器端)
import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.EOFException;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class Server extends JFrame {private JTextArea showDialog = null; // 定义文本区private ServerSocket serverSocket = null; // 定义接收插座private int port = 0; // 服务器应用程序所占的TCP端口号// 创建一个用来存放为每一个客户端提供服务的线程对象的集合List<ForClient> clients = new ArrayList<ForClient>();void init() {showDialog = new JTextArea(10, 20); // 设置文本区的大小this.add(new JScrollPane(showDialog)); // 将带有滚动条文本区添加在窗口中this.setTitle("117聊天室服务器端"); // 定义窗口属性this.setBounds(50, 50, 500, 400);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.validate();}void start() {this.init();port = 1111;try {serverSocket = new ServerSocket(port); // 将端口号接入插座接口showDialog.setText("服务器已就绪,等待客户端的连接请求。。" + "\n");while (true) {Socket socket = serverSocket.accept(); // 建立插座接口,实现连接。showDialog.append("连接已建立!" + "\n");ForClient client = new ForClient(socket); //clients.add(client); // 将对象存入集合里new Thread(client).start(); // 建立新的线程开始运行}} catch (IOException e) {// TODO Auto-generated catch blockSystem.out.println("服务器应用程序已经在运行,或该端口号已经被占用!");System.exit(0);}}public static void main(String[] args) {// TODO Auto-generated method stubServer serverWindow = new Server();serverWindow.start();}// 将一个客户端发送过来的消息转发给其他客户端private class ForClient implements Runnable {Socket socket = null;DataInputStream dis = null;DataOutputStream dos = null;public ForClient(Socket socket) {// TODO Auto-generated constructor stubthis.socket = socket;try {dis = new DataInputStream(socket.getInputStream());dos = new DataOutputStream(socket.getOutputStream());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic void run() {// TODO Auto-generated method stubboolean isQuit = true;while (isQuit) { // 不断读入收到的消息try {String mess = dis.readUTF();showDialog.append(mess + "\n");for (int i = 0; i < clients.size(); i++) {clients.get(i).send(mess); // 迭代器实现给多个客户端发送消息,转发功能。}} catch (EOFException e) {System.out.println("客户端已退出,随他去吧~" + "\n");showDialog.append("客户端已退出" + "\n");clients.remove(this); // 移除当前这个线程,调用remove方法for (int i = 0; i < clients.size(); i++) {clients.get(i).send("一个客户端已退出!!"); // 给其他的客户端发送消息,有一个客户端已退出。}isQuit = false; // 结束子线程,变量置为false} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}void send(String s) {try {dos.writeUTF(s);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}client.java(客户端)
import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import java.net.SocketException;import java.net.UnknownHostException;import javax.swing.Box;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTextArea;import javax.swing.JTextField;public class Client extends JFrame {private JTextArea showMessage = null; // 定义文本区private JTextField inputMessage = null; // 定义文本框private JButton sendBtn = null; // 定义发送按钮private Box boxH = null; // 定义一个水平盒子private Box boxV = null; // 定义一个垂直盒子private MyListener myListener = null; // 定义监听器对象private Socket socket = null; // 定义插座对象private DataInputStream dis = null; // 定义输入流管道private DataOutputStream dos = null; // 定义输出流管道private int serverPort = 1111; // 定义端口号private boolean isConnect = false; // 表示连接是否建立的变量void init() {showMessage = new JTextArea(20, 30); // 设置文本区的大小inputMessage = new JTextField(15); // 设置文本框的长度sendBtn = new JButton("发送");myListener = new MyListener(); // 建立监听对象事件inputMessage.addActionListener(myListener); // 文本框监听事件sendBtn.addActionListener(myListener); // 发送按钮监听事件/** * 1.创建水平的盒子容器 2.向水平盒子容器里添加输入文本框和发送按钮 */boxH = Box.createHorizontalBox(); // 水平盒子boxH.add(inputMessage); // 向boxH中添加输入文本框boxH.add(sendBtn); // 向boxH中添加发送按钮/** *1.创建垂直的盒子容器 2.向垂直盒子容器里添加滚动方格文本区,以及水平盒子 */boxV = Box.createVerticalBox(); // 垂直盒子boxV.add(new JScrollPane(showMessage)); // 添加滚动方格的文本区boxV.add(boxH); // 将boxH放入boxV中this.add(boxV); // 将boxV放入窗口this.setTitle("117聊天室客户端");this.setBounds(400, 400, 500, 500);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗口this.validate(); // 刷新,显示窗口内容addWindowListener(new WindowAdapter() { // 窗口适配器@Overridepublic void windowClosing(WindowEvent e) {super.windowClosing(e); // 关闭窗口disConnect(); // 关闭连接}});}void connect() {try {socket = new Socket("127.0.0.1", serverPort);showMessage.setText("已跟服务器建立连接!" + "\n");isConnect = true;} catch (UnknownHostException e) {showMessage.append("无法跟主机建立连接!请确认服务器地址是否打开!" + "\n");} catch (IOException e) {showMessage.append("无法跟服务器建立连接!请确定服务器已打开!" + "\n");}new Thread(new Runnable() { // 建立一个新的线程@Overridepublic void run() {// TODO Auto-generated method stubtry {dis = new DataInputStream(socket.getInputStream()); //while (isConnect) { // 当变量为true执行循环String mess = dis.readUTF(); // 定义mess字符串读取收到的数据showMessage.append(mess + "\n"); // 将数据显示在文本区showMessage}} catch (SocketException e) {// System.out.println("我已退出,你们聊吧。。");showMessage.append("服务器已关闭,都撤了吧。。");} catch (NullPointerException e) {System.out.println("服务器未开启,请确认。。");} catch (IOException e) {e.printStackTrace();}}}).start(); // 调用start方法}void disConnect() {isConnect = false; // 变量置为falsetry {if (dis != null)dis.close();if (dos != null)dos.close();if (socket != null)socket.close();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} finally {System.exit(0); // 退出程序}}void start() {this.init();this.connect(); // 向服务器发送连接请求}private class MyListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {String sendContent = inputMessage.getText().trim();// System.out.println(sendContent);try {dos = new DataOutputStream(socket.getOutputStream());dos.writeUTF(sendContent); //将输入的文本内容正常写出来,不会出现乱码inputMessage.setText(""); // 清空输入框} catch (IOException e1) {e1.printStackTrace();}}}public static void main(String[] args) {Client clientwindow = new Client(); // 创建一个客户端窗口clientwindow.start();}}