Netty实现TCP服务
客户端
package com.cnblogs.javalouvre;
import static io.netty.util.CharsetUtil.UTF_8;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LoggingHandler;
public class EchoClient {
private static final Logger log = LoggerFactory.getLogger(EchoClient.class);
private static final int PORT = 5678;
public static void main(String[] args) {
new EchoClient().bind();
}
private void bind() {
ChannelFuture channelFuture = null;
final Bootstrap bootstrap = new Bootstrap();
final EventLoopGroup group = new NioEventLoopGroup();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, Boolean.TRUE)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
final ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new LoggingHandler());
pipeline.addLast(new StringEncoder(UTF_8));
pipeline.addLast(new StringDecoder(UTF_8));
pipeline.addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
log.info("客户端收到消息:{}", msg);
}
});
}
});
try {
channelFuture = bootstrap.connect("127.0.0.1", PORT).sync();
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) {
log.info("客户端启动失败");
}
}
});
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String text;
while (!"quit".equalsIgnoreCase(text = bufferedReader.readLine())) {
channelFuture.channel().writeAndFlush(text);
}
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException | IOException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
服务端
package com.cnblogs.javalouvre;
import static java.nio.charset.StandardCharsets.UTF_8;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LoggingHandler;
public class EchoServer {
private static final Logger log = LoggerFactory.getLogger(EchoServer.class);
private static final int PORT = 5678;
public static void main(String[] args) {
new EchoServer().bind();
}
private void bind() {
final ServerBootstrap bootstrap = new ServerBootstrap();
final EventLoopGroup parentGroup = new NioEventLoopGroup(),
childGroup = new NioEventLoopGroup();
bootstrap.group(parentGroup, childGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
final ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast(new LoggingHandler());
pipeline.addLast(new StringEncoder(UTF_8));
pipeline.addLast(new StringDecoder(UTF_8));
pipeline.addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
log.info("服务器收到消息:{}", msg);
ctx.writeAndFlush("Hello " + msg);
}
});
}
});
try {
final ChannelFuture channelFuture = bootstrap.bind(PORT).sync();
channelFuture.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
if (!channelFuture.isSuccess()) {
log.info("服务启动失败");
}
}
});
channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
childGroup.shutdownGracefully();
parentGroup.shutdownGracefully();
}
}
}
-----------------------------------------------------------------------------------------------------------
薔薇猛虎皆成個性,陽光雨露俱是天恩!
薔薇猛虎皆成個性,陽光雨露俱是天恩!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理