| public class MyServer { |
| public static void main(String[] args) throws Exception{ |
| |
| EventLoopGroup bossGroup = new NioEventLoopGroup(1); |
| EventLoopGroup workerGroup = new NioEventLoopGroup(); |
| |
| try { |
| ServerBootstrap serverBootstrap = new ServerBootstrap(); |
| serverBootstrap.group(bossGroup,workerGroup).channel( |
| NioServerSocketChannel.class).childHandler(new MyServerInitializer()); |
| |
| ChannelFuture channelFuture = serverBootstrap.bind(7000).sync(); |
| channelFuture.channel().closeFuture().sync(); |
| |
| }finally { |
| bossGroup.shutdownGracefully(); |
| workerGroup.shutdownGracefully(); |
| } |
| |
| } |
| } |
| public class MyServerInitializer extends ChannelInitializer<SocketChannel> { |
| |
| @Override |
| protected void initChannel(SocketChannel ch) throws Exception { |
| ChannelPipeline pipeline = ch.pipeline(); |
| |
| |
| pipeline.addLast(new MyByteToLongDecoder()); |
| |
| |
| pipeline.addLast(new MyServerHandler()); |
| } |
| } |
| public class MyByteToLongDecoder extends ByteToMessageDecoder { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @Override |
| protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { |
| |
| System.out.println("MyByteToLongDecoder 被调用"); |
| |
| if(in.readableBytes() >= 8) { |
| out.add(in.readLong()); |
| } |
| } |
| } |
| public class MyServerHandler extends SimpleChannelInboundHandler<Long> { |
| @Override |
| protected void channelRead0(ChannelHandlerContext ctx, Long msg) throws Exception { |
| |
| System.out.println("从客户端" + ctx.channel().remoteAddress() + " 读取到long " + msg); |
| } |
| |
| @Override |
| public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { |
| cause.printStackTrace(); |
| ctx.close(); |
| } |
| } |
| public class MyClient { |
| public static void main(String[] args) throws Exception{ |
| |
| EventLoopGroup group = new NioEventLoopGroup(); |
| |
| try { |
| |
| Bootstrap bootstrap = new Bootstrap(); |
| bootstrap.group(group).channel(NioSocketChannel.class) |
| .handler(new MyClientInitializer()); |
| |
| ChannelFuture channelFuture = |
| bootstrap.connect("localhost", 7000).sync(); |
| |
| channelFuture.channel().closeFuture().sync(); |
| |
| }finally { |
| group.shutdownGracefully(); |
| } |
| } |
| } |
| public class MyClientInitializer extends ChannelInitializer<SocketChannel> { |
| @Override |
| protected void initChannel(SocketChannel ch) throws Exception { |
| |
| ChannelPipeline pipeline = ch.pipeline(); |
| |
| |
| pipeline.addLast(new MyLongToByteEncoder()); |
| |
| |
| pipeline.addLast(new MyClientHandler()); |
| } |
| } |
| public class MyLongToByteEncoder extends MessageToByteEncoder<Long> { |
| |
| @Override |
| protected void encode(ChannelHandlerContext ctx, Long msg, ByteBuf out) throws Exception { |
| |
| System.out.println("MyLongToByteEncoder encode 被调用"); |
| System.out.println("msg=" + msg); |
| out.writeLong(msg); |
| |
| } |
| } |
| public class MyClientHandler extends SimpleChannelInboundHandler<Long> { |
| @Override |
| protected void channelRead0(ChannelHandlerContext ctx, Long msg) throws Exception { |
| |
| System.out.println("服务器的ip=" + ctx.channel().remoteAddress()); |
| System.out.println("收到服务器消息=" + msg); |
| } |
| |
| |
| @Override |
| public void channelActive(ChannelHandlerContext ctx) throws Exception { |
| System.out.println("MyClientHandler 发送数据"); |
| |
| ctx.writeAndFlush(123456L); |
| } |
| } |
| |
| MyByteToLongDecoder 被调用 |
| 从客户端/127.0.0.1:53008 读取到long 123456 |
| |
| |
| MyClientHandler 发送数据 |
| MyLongToByteEncoder encode 被调用 |
| msg=123456 |
-
服务端发送long 到客户端

-
MyServerHandler中添加如下
| |
| ctx.writeAndFlush(98765L); |
| |
| pipeline.addLast(new MyLongToByteEncoder()); |
| |
| pipeline.addLast(new MyByteToLongDecoder()); |
| |
| MyByteToLongDecoder 被调用 |
| 从客户端/127.0.0.1:62913 读取到long 123456 |
| MyLongToByteEncoder encode 被调用 |
| msg=98765 |
| |
| |
| MyClientHandler 发送数据 |
| MyLongToByteEncoder encode 被调用 |
| msg=123456 |
| MyByteToLongDecoder 被调用 |
| 服务器的ip=localhost/127.0.0.1:7000 |
| 收到服务器消息=98765 |

| • 不论解码器handler 还是 编码器handler 即接收的消息类型必须与待处理的消息类型一致,否则该handler不会被执行 |
| • 在解码器 进行数据解码时,需要判断 缓存区(ByteBuf)的数据是否足够 ,否则接收到的结果会期望结果可能不一致 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2021-08-09 错误处理
2021-08-09 spring boot文件上传