局域网聊天

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.Base64;
import org.json.JSONObject;

public class ChatClient {
    private static final String SERVER_IP = "127.0.0.1";
    private static final int SERVER_PORT = 12345;
    private static final String SECRET_KEY = "1234567890123456"; // 16 字节密钥

    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    private String nickname;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(ChatClient::new);
    }

    public ChatClient() {
        initGUI();
    }

    private void initGUI() {
        JFrame frame = new JFrame("局域网聊天");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 500);

        JTextArea chatArea = new JTextArea();
        chatArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(chatArea);

        JTextField inputField = new JTextField();
        JButton sendButton = new JButton("发送");

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(inputField, BorderLayout.CENTER);
        panel.add(sendButton, BorderLayout.EAST);

        frame.add(scrollPane, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.SOUTH);

        frame.setVisible(true);

        sendButton.addActionListener(e -> sendMessage(inputField, chatArea));
        inputField.addActionListener(e -> sendMessage(inputField, chatArea));

        String userNickname = JOptionPane.showInputDialog(frame, "请输入昵称:");
        if (userNickname == null || userNickname.trim().isEmpty()) {
            System.exit(0);
        }
        this.nickname = userNickname;

        try {
            connectToServer(chatArea);
        } catch (IOException e) {
            JOptionPane.showMessageDialog(frame, "无法连接到服务器!", "错误", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
    }

    private void connectToServer(JTextArea chatArea) throws IOException {
        socket = new Socket(SERVER_IP, SERVER_PORT);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);

        // 发送昵称
        JSONObject json = new JSONObject();
        json.put("nickname", nickname);
        sendEncryptedMessage(json.toString());

        new Thread(() -> {
            try {
                String encryptedMessage;
                while ((encryptedMessage = in.readLine()) != null) {
                    String decryptedMessage = decrypt(encryptedMessage);
                    chatArea.append(decryptedMessage + "\n");
                }
            } catch (Exception e) {
                chatArea.append("与服务器断开连接。\n");
            }
        }).start();
    }

    private void sendMessage(JTextField inputField, JTextArea chatArea) {
        String message = inputField.getText().trim();
        if (message.isEmpty()) return;

        inputField.setText("");
        try {
            JSONObject json = new JSONObject();
            json.put("message", message);
            sendEncryptedMessage(json.toString());
        } catch (Exception e) {
            chatArea.append("消息发送失败。\n");
        }
    }

    private void sendEncryptedMessage(String message) throws Exception {
        String encryptedMessage = encrypt(message);
        out.println(encryptedMessage);
    }

    private String encrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes()));
    }

    private String decrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance("AES");
        SecretKeySpec key = new SecretKeySpec(SECRET_KEY.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(Base64.getDecoder().decode(data)));
    }
}

客户端

 1 import java.io.*;
 2 import java.net.*;
 3 import java.util.*;
 4 
 5 public class ChatServer {
 6     private static final int PORT = 12345;
 7     private static Set<Socket> clientSockets = Collections.synchronizedSet(new HashSet<>());
 8 
 9     public static void main(String[] args) {
10         System.out.println("服务器启动,等待客户端连接...");
11         try (ServerSocket serverSocket = new ServerSocket(PORT)) {
12             while (true) {
13                 Socket clientSocket = serverSocket.accept();
14                 clientSockets.add(clientSocket);
15                 System.out.println("客户端连接:" + clientSocket.getInetAddress());
16 
17                 // 启动新线程处理该客户端的消息
18                 new Thread(() -> handleClient(clientSocket)).start();
19             }
20         } catch (IOException e) {
21             e.printStackTrace();
22         }
23     }
24 
25     private static void handleClient(Socket clientSocket) {
26         try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
27              PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true)) {
28 
29             out.println("欢迎加入聊天!");
30             String message;
31             while ((message = in.readLine()) != null) {
32                 System.out.println("收到消息:" + message);
33                 broadcastMessage("客户端 " + clientSocket.getInetAddress() + ":" + message);
34             }
35         } catch (IOException e) {
36             System.out.println("客户端断开:" + clientSocket.getInetAddress());
37         } finally {
38             try {
39                 clientSockets.remove(clientSocket);
40                 clientSocket.close();
41             } catch (IOException e) {
42                 e.printStackTrace();
43             }
44         }
45     }
46 
47     private static void broadcastMessage(String message) {
48         synchronized (clientSockets) {
49             for (Socket socket : clientSockets) {
50                 try {
51                     PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
52                     out.println(message);
53                 } catch (IOException e) {
54                     e.printStackTrace();
55                 }
56             }
57         }
58     }
59 }

服务端

posted on 2025-01-31 14:41  shenhshihao  阅读(6)  评论(0)    收藏  举报

导航