【Netty】Socket 编程(C/S):基于Netty的Server、Client示例(少注释)
程序员文章站
2022-08-31 10:21:43
首先引入 Netty 的依赖 io.netty netty-all 4.1.36.Final Serverpublic class NettyServer { public static vo...
首先引入 Netty 的依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
Server
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new NettyServerInitailizer())
.option(ChannelOption.SO_BACKLOG, 128);
ChannelFuture channelFuture = serverBootstrap.bind(8000).sync();
System.out.println("Netty Server started...");
channelFuture.channel().closeFuture().sync();
} catch (Exception e){
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
public class NettyServerInitailizer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) {
ChannelPipeline pipeline = socketChannel.pipeline();
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
// pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new NettyServerHandler());
}
}
/**
* SimpleChannelInboundHandler 是 ChannelInboundHandlerAdapter 的子类
*/
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
/**
* 有新的客户端连接时触发
*
* @param ctx 上下文对象, 含有通道channel,管道pipeline
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("新的客户端..." + ctx.channel().remoteAddress());
}
/**
* 读取客户端发送的数据
*
* @param ctx 上下文对象, 含有通道channel,管道pipeline
* @param msg 就是客户端发送的数据
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
// 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
System.out.println(ctx.channel().remoteAddress() +":" + msg);
ctx.channel().writeAndFlush("Hello Client --"+ UUID.randomUUID().toString().substring(0,7));
}
/**
* 处理异常, 一般是需要关闭通道
*
* @param ctx
* @param cause
* @throws Exception
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
Client
public class NettyClient {
public static void main(String[] args){
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(eventLoopGroup)
.channel(NioSocketChannel.class)
.handler(new NettyClientInitailizer())
ChannelFuture channelFuture = bootstrap.connect("localhost",8000).sync();
System.out.println("Netty Client started...");
channelFuture.channel().closeFuture().sync();
} catch (Exception e){
e.printStackTrace();
}
finally {
eventLoopGroup.shutdownGracefully();
}
}
}
public class NettyClientInitailizer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
// pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
// pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new NettyClientHandler());
}
}
public class NettyClientHandler extends SimpleChannelInboundHandler<String> {
/**
* 当客户端连接服务器完成就会触发该方法
*
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("成功连接到服务端..." + ctx.channel().remoteAddress());
// 注:因为已经引入了编解码器,所以这里直接就是可以读写 String 类型消息,不用再先包装成 ByteBuf
ctx.writeAndFlush("Hello Server!");
}
/**
* 当通道有读取事件时会触发,即服务端发送数据给客户端
*
* @param ctx 上下文对象, 含有通道channel,管道pipeline
* @param msg 就是客户端发送的数据
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("Server:"+ msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
先后启动 Server 和 Client,结果如下:
本文地址:https://blog.csdn.net/weixin_43935927/article/details/111993298