Java Socket 私聊

简介

在计算机网络中,Socket是一种提供基于TCP/IP协议的网络通信的API。使用Socket可以在不同的计算机之间进行数据传输和通信。在Java中,提供了Socket类和ServerSocket类来实现网络通信。本文将介绍如何使用Java Socket实现私聊功能。

Socket通信原理

Socket通信的原理是基于客户端-服务器模型,其中服务器端通过监听指定端口,等待客户端连接。一旦有客户端连接,服务器端就会创建一个新的线程与该客户端进行通信。客户端通过指定服务器的IP地址和端口号来连接服务器。

代码示例

下面是一个简单的Java Socket私聊的代码示例。

// 服务器端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务器已启动,等待客户端连接...");

            Socket clientSocket = serverSocket.accept();
            System.out.println("客户端已连接:" + clientSocket.getInetAddress().getHostAddress());

            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            String message;
            while ((message = in.readLine()) != null) {
                System.out.println("收到客户端发来的消息:" + message);
                out.println("服务器已收到消息:" + message);
            }

            in.close();
            out.close();
            clientSocket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        try {
            Socket clientSocket = new Socket("localhost", 8888);
            System.out.println("已连接服务器");

            BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

            String message;
            while ((message = reader.readLine()) != null) {
                out.println(message);
                System.out.println("服务器回复:" + in.readLine());
            }

            in.close();
            out.close();
            reader.close();
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码中,服务器端首先创建一个ServerSocket对象,并指定监听的端口号为8888。然后通过serverSocket.accept()方法等待客户端连接,一旦有客户端连接,则创建一个新的Socket对象进行通信。服务器端通过BufferedReader读取客户端发来的消息,通过PrintWriter向客户端发送消息。

客户端首先创建一个Socket对象,并指定服务器的IP地址和端口号。然后通过BufferedReader获取用户输入的消息,并通过PrintWriter向服务器发送消息。客户端同样需要通过BufferedReader读取服务器发来的消息。

私聊实现

要实现私聊功能,我们可以在服务器端维护一个客户端列表,并为每个客户端创建一个独立的线程进行通信。当某个客户端发送私聊消息时,服务器端将消息发送给指定的客户端。

下面是一个简单的私聊功能的代码示例。

// 服务器端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Server {
    private static List<Socket> clients = new ArrayList<>();

    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务器已启动,等待客户端连接...");

            while (true) {
                Socket clientSocket = serverSocket.accept();
                clients.add(clientSocket);
                System.out.println("客户端已连接:" + clientSocket.getInetAddress().getHostAddress());

                new Thread(() -> {
                    try {
                        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

                        String message;
                        while ((message = in.readLine()) != null) {
                            System.out.println("收到客户端发来的消息:" + message);
                            if (message.startsWith("@")) {
                                String[] splitMsg = message.split(" ");
                                String receiver = splitMsg