Java网络聊天室

在现代社交网络的时代,聊天室已经成为人们交流的重要手段之一。而网络聊天室则使得人们可以跨越时空的限制,实时地与他人进行聊天。本文将介绍如何使用Java编程语言实现一个简单的网络聊天室,并提供相应的代码示例。

简介

网络聊天室是一个典型的客户端-服务器(Client-Server)模型应用程序。在该模型中,服务器负责接收客户端的连接请求,并将消息转发给其他客户端。客户端负责发送消息给服务器,并接收服务器转发的其他客户端的消息。

实现

我们可以使用Java的Socket和ServerSocket类来实现网络通信功能。Socket类表示一个客户端套接字,ServerSocket类表示一个服务器套接字。

服务器端

首先,我们需要创建一个服务器端的类,用于监听客户端的连接请求,并接收和转发消息。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class ChatServer {
    private int port;
    private List<ClientHandler> clients;

    public ChatServer(int port) {
        this.port = port;
        this.clients = new ArrayList<>();
    }

    public void start() {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("Server started on port " + port);

            while (true) {
                Socket clientSocket = serverSocket.accept();
                System.out.println("New client connected: " + clientSocket);

                ClientHandler client = new ClientHandler(clientSocket, this);
                clients.add(client);
                client.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void broadcast(String message, ClientHandler sender) {
        for (ClientHandler client : clients) {
            if (client != sender) {
                client.sendMessage(message);
            }
        }
    }

    public void removeClient(ClientHandler client) {
        clients.remove(client);
    }

    public static void main(String[] args) {
        ChatServer server = new ChatServer(8000);
        server.start();
    }
}

在上述代码中,我们使用ServerSocket类打开一个服务器套接字,并使用accept()方法等待客户端的连接请求。当有客户端连接成功后,我们创建一个新的ClientHandler线程来处理该客户端的消息。

客户端

接下来,我们需要创建一个客户端的类,用于与服务器进行通信。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ChatClient {
    private String hostname;
    private int port;
    private String username;

    public ChatClient(String hostname, int port, String username) {
        this.hostname = hostname;
        this.port = port;
        this.username = username;
    }

    public void start() {
        try {
            Socket socket = new Socket(hostname, port);

            BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter outputWriter = new PrintWriter(socket.getOutputStream(), true);

            System.out.println("Connected to the server.");

            // 发送用户名给服务器
            outputWriter.println(username);

            // 创建一个新的接收线程来接收服务器转发的消息
            Thread receiveThread = new Thread(new ReceiveHandler(inputReader));
            receiveThread.start();

            // 从控制台读取用户输入并发送给服务器
            BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
            String message;
            while ((message = consoleReader.readLine()) != null) {
                outputWriter.println(message);
            }

            // 关闭连接
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ChatClient client = new ChatClient("localhost", 8000, "Alice");
        client.start();
    }
}

在上述代码中,我们使用Socket类连接到服务器,并创建了一个输入流和一个输出流。我们通过输出流向服务器发送用户名,然后创建一个新的线程来接收服务器转发的消息。同时,我们从控制台读取用户输入,并通过输出流发送给服务器。

客户端处理器

客户端处理器是一个Runnable的实现类,用于处理服务器转发的消息。

import java.io.BufferedReader;
import java.io.IOException;

public class ReceiveHandler implements Runnable {
    private BufferedReader reader;

    public ReceiveHandler(BufferedReader reader) {
        this.reader = reader;
    }

    @Override
    public void run() {
        try {
            String message;
            while ((message = reader.readLine()) != null) {