Java Socket实现聊天室附1500行源代码

Java Socket实现聊天室是一种常见的网络应用程序,该应用程序使用Socket API实现了客户端和服务器端之间的连接。本攻略通过讲解如何使用Java Socket API实现一个聊天室,来帮助开发者了解Java Socket编程的基本原理和用法。

概述

Java Socket API是Java语言提供的一个用于网络通信的API,它允许程序员使用Socket、ServerSocket和DatagramSocket等类来实现基于TCP和UDP的网络通信。在本攻略中,我们将使用Java Socket API来开发一个简单的聊天室程序,用户可以通过这个聊天室和其他用户进行交流。

程序设计

客户端

  1. 首先,我们需要创建一个客户端类,该类用于连接到服务器和发送、接收数据。
public class Client {
    private String serverIp;
    private int serverPort;
    private Socket socket;
    private BufferedReader bufferedReader;
    private PrintWriter printWriter;

    public Client(String serverIp, int serverPort) throws IOException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        this.socket = new Socket(serverIp, serverPort);
        this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        this.printWriter = new PrintWriter(socket.getOutputStream());
    }

    public void send(String message) {
        printWriter.println(message);
        printWriter.flush();
    }

    public String receive() throws IOException {
        return bufferedReader.readLine();
    }

    public void close() throws IOException {
        socket.close();
    }
}
  1. 然后,我们需要创建一个用于等待用户输入并发送消息的类。
public class WriteThread implements Runnable {
    private Client client;

    public WriteThread(Client client) {
        this.client = client;
    }

    @Override
    public void run() {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            String message = scanner.nextLine();
            client.send(message);
        }
    }
}
  1. 接下来,我们需要创建一个用于接收消息的类。
public class ReadThread implements Runnable {
    private Client client;

    public ReadThread(Client client) {
        this.client = client;
    }

    @Override
    public void run() {
        try {
            while (true) {
                String message = client.receive();
                System.out.println(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 最后,我们将客户端连接到服务器并启动读写线程。
public class ClientMain {
    public static void main(String[] args) throws Exception {
        Client client = new Client("localhost", 8000);

        Thread writeThread = new Thread(new WriteThread(client));
        writeThread.start();

        Thread readThread = new Thread(new ReadThread(client));
        readThread.start();
    }
}

服务器端

  1. 首先,我们需要创建一个服务器类,该类用于等待客户端的连接并处理客户端的请求。
public class Server {
    private int port;
    private Map<String, Socket> socketMap;

    public Server(int port) {
        this.port = port;
        this.socketMap = new HashMap<>();
    }

    public void start() throws IOException {
        ServerSocket serverSocket = new ServerSocket(port);
        while (true) {
            Socket socket = serverSocket.accept();
            String user = UUID.randomUUID().toString();
            socketMap.put(user, socket);
            new Thread(new HandlerThread(user, socket)).start();
        }
    }

    public void send(String user, String message) throws IOException {
        Socket socket = socketMap.get(user);
        PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
        printWriter.println(message);
    }

    public void broadcast(String message) throws IOException {
        for (Socket socket : socketMap.values()) {
            PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
            printWriter.println(message);
        }
    }

    public void close() throws IOException {
        for (Socket socket : socketMap.values()) {
            socket.close();
        }
    }
}
  1. 然后,我们需要创建一个线程类,该类用于处理客户端的请求。
public class HandlerThread implements Runnable {
    private String user;
    private Socket socket;

    public HandlerThread(String user, Socket socket) {
        this.user = user;
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            while (true) {
                String message = bufferedReader.readLine();
                if (message.equals("exit")) {
                    socket.close();
                    break;
                }
                ServerMain.server.send(user, message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  1. 最后,我们将服务器端启动。
public class ServerMain {
    public static Server server;

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

示例说明

下面给出两个示例说明。

示例一:本地运行

  1. 首先,我们需要打开一个命令行窗口,进入到聊天室程序的源代码目录。

  2. 然后,我们需要启动服务器端程序以等待客户端的连接。

java ServerMain
  1. 接下来,我们需要启动客户端程序以连接到服务器。
java ClientMain
  1. 现在,我们可以在客户端程序中输入消息并发送到服务器端,同时可以在客户端程序中接收其他客户端发送的消息。

示例二:远程运行

  1. 首先,我们需要在远程计算机上启动服务器端程序。
java ServerMain
  1. 然后,我们需要在本地计算机上启动客户端程序并连接到远程服务器。
java ClientMain "server_ip_address"

其中,"server_ip_address"表示远程服务器的公网IP地址。

  1. 现在,我们可以在本地客户端程序中输入消息并发送到远程服务器端,同时可以在本地客户端程序中接收其他客户端发送的消息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java Socket实现聊天室附1500行源代码 - Python技术站

(0)
上一篇 2023年5月24日
下一篇 2023年5月24日

相关文章

  • SpringBoot RESTful风格入门讲解

    SpringBoot RESTful 风格入门讲解 什么是 RESTful 风格 RESTful 是一种 Web 架构风格,用于开发 Web API。它基于 HTTP 协议,使用 HTTP 中的 GET、POST、PUT、DELETE 等方法,并使用 URL 作为资源的唯一标识,返回 JSON 或 XML 格式的数据。通过 RESTful 风格可以实现 We…

    Java 2023年5月31日
    00
  • 深入理解Java中包的定义与使用

    我来为您详细讲解“深入理解Java中包的定义与使用”的完整攻略。 什么是Java包? Java包是一种将类组织在一起的机制。它们用于避免命名冲突,使类更加可维护,并提供了更好的封装和安全性。Java包是Java的基本组成部分之一,几乎所有的Java程序都使用了它们。 Java包的定义 Java包的定义非常简单 —— 它是一个具有唯一名称的目录,其中包含Jav…

    Java 2023年5月26日
    00
  • Java数组扩容实例代码

    下面我来为你详细讲解Java数组扩容实例代码的完整攻略。 1. 初探数组扩容 在Java中,数组是一种非常常用的数据结构,但是数组的长度是固定的,无法动态增长,这会限制数组的使用。为了解决这个问题,我们可以使用Java的数组扩容机制,实现数组的动态增长。 1.1 数组扩容原理 当数组不够用时,我们需要创建一个新的更大的数组来替换原来的数组。具体步骤为: 创建…

    Java 2023年5月23日
    00
  • java中复杂查询sql语句该怎么写

    讲解如下。 如何在Java中编写复杂查询SQL语句 在Java中编写复杂查询SQL语句通常有两种方式,分别是使用字符串拼接和使用JPA Criteria Query API。下面将对这两种方法进行详细介绍。 字符串拼接 使用字符串拼接方式,我们可以直接写出SQL语句并将其作为一个字符串传递给JDBC,然后通过执行该语句返回结果集。这种方式的优点是简单易懂,可…

    Java 2023年5月20日
    00
  • Spring MVC自定义日期类型转换器实例详解

    Spring MVC自定义日期类型转换器实例详解 1. 什么是日期类型转换器? Spring MVC在处理表单数据时,会将用户提交的数据绑定到Controller的方法参数或者是JavaBean里面,但是很多数据是无法直接转换为Java的内置类型,比如日期类型。这个时候就需要使用日期类型转换器来进行转换。日期类型转换器的作用是将用户提交的日期字符串或者其他格…

    Java 2023年6月15日
    00
  • 【C#基础】Substring截取字符串的方法小结(推荐)

    当我们需要截取一个字符串的部分内容时,可以使用C#内置的Substring方法,它可以根据指定的位置和长度,从原始字符串中截取出一个新字符串。 Substring方法的基本使用 Substring方法用于截取字符串的一部分,可以根据指定的位置和长度获取字符串的一部分内容,其基本语法如下: public string Substring(int startIn…

    Java 2023年5月19日
    00
  • Java中的finally语句块是什么?

    下面是详细讲解Java中的finally语句块的完整攻略。 finally语句块是什么? finally语句块是Java中的一种异常处理机制。当发生try块中的异常或代码块中的return语句时,代码执行流将跳转到finally块中执行。无论是否抛出异常,finally语句块中的语句都会执行。finally块通常用于释放资源或在程序执行出错时做一些清理工作。…

    Java 2023年4月27日
    00
  • 使用Java实现5种负载均衡算法实例

    使用Java实现5种负载均衡算法的完整攻略如下: 算法简介 负载均衡是指将请求分配到多个服务器上以达到最大化利用每个服务器的目的。在实际应用中,常用的负载均衡算法有很多种,常见的有以下五种: 轮询算法:按照服务器列表中的顺序依次将请求分配到每台服务器上,然后再从头开始,循环分配请求。轮询算法适用于所有的服务器具有相同的处理能力并且请求量相差不大的情况。 随机…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部