3.客户端实现代码
客户端的代码实现也是分为以下 3 个部分:
- MyNettyClient:客户端核心业务代码;
- ClientInitializer:客户端通道初始化;
- ClientHandler:接收到消息之后的处理逻辑。
客户端的实现代码如下:
/** * 客户端 */ static class MyNettyClient { public static void main(String[] args) { // 创建事件循环线程组(客户端的线程组只有一个) EventLoopGroup group = new NioEventLoopGroup(); try { // Netty 客户端启动对象 Bootstrap b = new Bootstrap(); // 设置启动参数 b.group(group) // 设置通道类型 .channel(NioSocketChannel.class) // 设置启动执行器(负责启动事件的业务执行,ClientInitializer 为自定义的类) .handler(new ClientInitializer()); // 连接服务器端并同步通道 Channel ch = b.connect("127.0.0.1", 8007).sync().channel(); // 发送消息 ChannelFuture lastWriteFuture = null; // 给服务器端发送 10 条消息 for (int i = 0; i < 10; i++) { // 发送给服务器消息 lastWriteFuture = ch.writeAndFlush("Hi,Java."); } // 在关闭通道之前,同步刷新所有的消息 if (lastWriteFuture != null) { lastWriteFuture.sync(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放资源 group.shutdownGracefully(); } } } /** * 客户端通道初始化类 */ static class ClientInitializer extends ChannelInitializer<SocketChannel> { // 字符串编码器和解码器 private static final StringDecoder DECODER = new StringDecoder(); private static final StringEncoder ENCODER = new StringEncoder(); // 客户端连接成功之后业务处理 private static final ClientHandler CLIENT_HANDLER = new ClientHandler(); /** * 初始化客户端通道 */ @Override public void initChannel(SocketChannel ch) { ChannelPipeline pipeline = ch.pipeline(); // 设置(字符串)编码器和解码器 pipeline.addLast(DECODER); pipeline.addLast(ENCODER); // 客户端连接成功之后的业务处理 pipeline.addLast(CLIENT_HANDLER); } } /** * 客户端连接成功之后的业务处理 */ static class ClientHandler extends SimpleChannelInboundHandler<String> { /** * 读取到服务器端的消息 */ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) { System.err.println("接到服务器的消息:" + msg); } /** * 异常处理,打印异常并关闭通道 */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
从以上代码可以看出,我们代码实现的功能是,客户端给服务器端发送 10 条消息。
编写完上述代码之后,我们就可以启动服务器端和客户端了,启动之后,它们的执行结果如下:
从上述结果中可以看出,虽然客户端和服务器端实现了通信,但在 Netty 的使用中依然存在粘包的问题,服务器端一次收到了 10 条消息,而不是每次只收到一条消息,因此接下来我们要解决掉 Netty 中的粘包问题。