【Netty】使用Netty搭建简易Sokect客户端
直接上代码
创建客户端,连接到服务端,并发送消息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** 发送一条消息到socket服务端*/ private void sendOne(String rawMessage) { NioEventLoopGroup 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 MyDecoder()) .addLast( new MyEncoder()) .addLast( new MyClientHandler()); } }); ChannelFuture future = bootstrap.connect( "192.168.1.101" , 4000 ).sync(); //发送消息 future.channel().writeAndFlush(rawMessage); future.channel().closeFuture().sync(); } catch (Exception e) { log.error( "发送消息异常" , e); } finally { group.shutdownGracefully(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | //解码 服务端返回信息解码工具 public class MyDecoder extends DelimiterBasedFrameDecoder { private static final int MAX_FRAME_LENGTH = 4096 ; //和服务端约定的起始字符和中止字符 private static char startByte = ( char ) 11 ; private static char endByte1 = ( char ) 28 ; private static char endByte2 = ( char ) 13 ; public MyDecoder() { super (MAX_FRAME_LENGTH, true , Unpooled.copiedBuffer( new char []{endByte1, endByte2}, StandardCharsets.UTF_8)); } @Override protected Object decode(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { ByteBuf buf = (ByteBuf) super .decode(ctx, buffer); if (buf != null ) { try { int pos = buf.bytesBefore(( byte ) startByte); if (pos >= 0 ) { ByteBuf msg = buf.readerIndex(pos + 1 ).slice(); return asString(msg); } else { throw new DecoderException( "找不到开始符号:" + Integer.toHexString(startByte)); } } finally { buf.release(); } } return null ; } private String asString(ByteBuf msg) { String text = msg.toString(StandardCharsets.UTF_8); return text; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | //编码 对发送的消息进行编码 public class MyEncoder extends MessageToByteEncoder<Object> { private static char startByte = ( char ) 11 ; private static char endByte1 = ( char ) 28 ; private static char endByte2 = ( char ) 13 ; @Override protected void encode(ChannelHandlerContext channelHandlerContext, Object message, ByteBuf byteBuf) throws Exception { byte [] body; if (message instanceof String) { body = ((String) message).getBytes(StandardCharsets.UTF_8); } else if (message instanceof byte []) { body = ( byte []) message; } else { throw new IllegalArgumentException( "不支持的类型:" + message.getClass().getCanonicalName()); } byteBuf.writeByte(startByte); byteBuf.writeBytes(body); byteBuf.writeByte(endByte1); byteBuf.writeByte(endByte2); } } |
1 2 3 4 5 6 7 8 9 10 | //收到服务端返回消息后的处理,此处逻辑为直接关闭通道,即结束通讯 @ChannelHandler .Sharable public class MyClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { //收到服务器返回信息后,关闭通道。 ctx.channel().close(); } } |
以上方式为通过各方信息整合后,得到的符合自身需求的一个Netty客户端发送消息的编码,经过了测试和验证,满足发送一条消息到服务端,收到服务端返回信息后关闭通道的需要。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理