在 Java 中实现 TCP 长连接有多种方式,下面我将为你详细介绍两种常见的方式:Socket 和 Netty。每种方式都将包括步骤流程和示例代码,并提供 Maven 和 Gradle 的依赖坐标。
步骤流程:
ServerSocket 监听指定端口,客户端使用 Socket 连接服务器的 IP 和端口。示例代码:
服务器端:
import java.io.*;
import java.net.*;
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(12345);
        System.out.println("Server is listening...");
        while (true) {
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected: " + clientSocket.getInetAddress());
            // Handle client communication using input/output streams
            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("Received: " + message);
                out.println("Server received: " + message);
            }
            clientSocket.close();
        }
    }
}
客户端:
import java.io.*;
import java.net.*;
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 12345);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
        String userInput;
        while ((userInput = consoleReader.readLine()) != null) {
            out.println(userInput);
            String response = in.readLine();
            System.out.println("Server response: " + response);
        }
        socket.close();
    }
}
依赖坐标:
这种方式不需要任何第三方库的依赖。
步骤流程:
示例代码:
服务器端:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class Server {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                           .channel(NioServerSocketChannel.class)
                           .childHandler(new ChannelInitializer<SocketChannel>() {
                               @Override
                               protected void initChannel(SocketChannel ch) {
                                   ch.pipeline().addLast(new ServerHandler());
                               }
                           });
            ChannelFuture future = serverBootstrap.bind(12345).sync();
            System.out.println("Server is listening...");
            future.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
服务器处理器:
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buffer = (ByteBuf) msg;
        byte[] bytes = new byte[buffer.readableBytes()];
        buffer.readBytes(bytes);
        String message = new String(bytes);
        System.out.println("Received: " + message);
        // Send response
        ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("Server received: ".getBytes()).writeBytes(bytes));
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
客户端:
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.util.Scanner;
public class Client {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                     .channel(NioSocketChannel.class)
                     .handler(new ChannelInitializer<SocketChannel>() {
                         @Override
                         protected void initChannel(SocketChannel ch) {
                             ch.pipeline().addLast(new ClientHandler());
                         }
                     });
            Channel channel = bootstrap.connect("localhost", 12345).sync().channel();
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String userInput = scanner.nextLine();
                ByteBuf messageBuffer = Unpooled.copiedBuffer(userInput.getBytes());
                channel.writeAndFlush(messageBuffer);
            }
        } finally {
            group.shutdownGracefully();
        }
    }
}
客户端处理器:
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf buffer = (ByteBuf) msg;
        byte[] bytes = new byte[buffer.readableBytes()];
        buffer.readBytes(bytes);
        String response = new String(bytes);
        System.out.println("Server response: " + response);
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
依赖坐标:
在 Maven 中添加 Netty 的依赖:
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.68.Final</version>
</dependency>
在 Gradle 中添加 Netty 的依赖:
implementation 'io.netty:netty-all:4.1.68.Final'
这些示例代码和步骤流程应该能帮助你实现 TCP 长连接,无论是使用原生 Socket 还是 Netty。注意,这些代码仅作为示例,实际项目中可能需要根据需求进行更多的细节处理和错误处理。