JAVA程序设计-作业4-JAVA综合编程

要求:编写带图形界面的聊天程序,实现让客户可以持续地发送消息给服务器,服务器也可以即时看到客户端发送的消息,并回消息给客户端。 程序运行界面如下:

服务器代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;


public class Server implements ActionListener {
   JTextArea textArea;
   JTextField textField;
   JButton sendButton;
   ServerSocket serverSocket;
   List<ClientThread> clients;

   public static void main(String[] args) {
       new Server().start();
   }

   public Server() {
       JFrame frame = new JFrame("服务器");

       JPanel panel = new JPanel(new BorderLayout());
       textArea = new JTextArea(20, 60);
       textArea.setEditable(false);
       JScrollPane scrollPane = new JScrollPane(textArea);
       panel.add(BorderLayout.CENTER, scrollPane);

       // 添加输入框和发送按钮
       JPanel bottomPanel = new JPanel(new BorderLayout());
       textField = new JTextField(40);
       bottomPanel.add(BorderLayout.CENTER, textField);
       sendButton = new JButton("发送");
       sendButton.addActionListener(this);
       bottomPanel.add(BorderLayout.EAST, sendButton);
       panel.add(BorderLayout.SOUTH, bottomPanel);

       frame.setContentPane(panel);
       frame.setSize(400,300);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setVisible(true);
   }

   public void start() {
       try {
           serverSocket = new ServerSocket(8000);
           clients = new ArrayList<ClientThread>();
           while (true) {
               Socket socket = serverSocket.accept();
               ClientThread clientThread = new ClientThread(socket,textArea);
               clients.add(clientThread);
               clientThread.start();
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   public synchronized void removeFromClients(ClientThread clientThread) {
       clients.remove(clientThread);
   }

   @Override
   public void actionPerformed(ActionEvent event) {
       String message = textField.getText();
       if (!message.equals("")) {
           // 发送消息给所有客户端
           for (ClientThread client : clients) {
               client.sendToClient("服务器说: " + message);
           }
           textField.setText("");
       }
   }

   class ClientThread extends Thread {
       Socket socket;
       DataInputStream dis;
       DataOutputStream dos;
       JTextArea textArea;

       public ClientThread(Socket socket, JTextArea textArea) {
           this.socket = socket;
           this.textArea = textArea;
           try {
               dis = new DataInputStream(socket.getInputStream());
               dos = new DataOutputStream(socket.getOutputStream());
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

       public void close() {
           try {
               dos.writeUTF("exit");
               socket.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

       public void sendToClient(String message) {
           try {
               synchronized (this) {
                   dos.writeUTF(message);
                   textArea.append(message + "\n"); // 在客户端窗口中显示消息记录
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

       @Override
       public void run() {
           try {
               String name = dis.readUTF();
               textArea.append(name + "连接成功!\n"); // 添加消息提示
               while (true) {
                   String message = dis.readUTF();
                   if (message.equals("exit")) {
                       break;
                   }
                   textArea.append("客户端" + "说: " + message + "\n"); // 在服务器窗口中显示消息记录
               }
               textArea.append(name + "离开了!\n");
               removeFromClients(this);
               socket.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

       public void sendToAllClients(String message) {
           for (ClientThread client : clients) {
               try {
                   synchronized (client) {
                       if (!this.equals(client)) { // 不要发送给自己
                           client.sendToClient(message);
                       }
                       client.dos.writeUTF(message);
                       client.textArea.append(message + "\n"); // 在客户端窗口中显示消息
                   }
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }

   }
}

客户端代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;


public class Client {
   JTextArea textArea;
   JTextField textField;
   Socket socket;
   DataInputStream dis;
   DataOutputStream dos;

   public static void main(String[] args){
       new Client().start();
   }

   public Client() {
       JFrame frame = new JFrame("客户端");
       JPanel panel = new JPanel(new BorderLayout());
       textArea = new JTextArea(20, 60);
       textArea.setEditable(false);
       JScrollPane scrollPane = new JScrollPane(textArea);
       panel.add(BorderLayout.CENTER, scrollPane);

       // 添加输入框和发送按钮
       JPanel bottomPanel = new JPanel(new BorderLayout());
       textField = new JTextField(40);
       bottomPanel.add(BorderLayout.CENTER, textField);
       JButton sendButton = new JButton("发送");
       sendButton.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent event) {
               sendMessage();
           }
       });

       bottomPanel.add(BorderLayout.EAST, sendButton);
       panel.add(BorderLayout.SOUTH, bottomPanel);


       frame.setContentPane(panel);
       frame.setSize(400,300);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setVisible(true);

   }

   public void start() {
       try {
           socket = new Socket("127.0.0.1", 8000);
           dis = new DataInputStream(socket.getInputStream());
           dos = new DataOutputStream(socket.getOutputStream());
           String name = JOptionPane.showInputDialog("请输入你的姓名:");
           dos.writeUTF(name);
           Thread listenThread = new ListenThread();
           listenThread.start();
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   public void sendMessage() {
       try {
           String message = textField.getText();
           if (!message.equals("")) {
               dos.writeUTF(message);
               // 在聊天记录中显示客户端说的话
               textArea.append("客户端说: " + message + "\n");
           }
           textField.setText("");
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

   class ListenThread extends Thread {
       @Override
       public void run() {
           try {
               while (!socket.isClosed()) {
                   String message = dis.readUTF();
                   textArea.append(message + "\n");
               }
           } catch (IOException e) {
               e.printStackTrace();

           } finally {
               try {
                   if (dis != null) dis.close();
                   if (dos != null) dos.close();
                   if (socket != null) socket.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
       }
   }
}

运行程序时,先启动服务器,再启动客户端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值