文章目录
- 一、前言介绍
- 二、代码实现
- 2.1 工程结构
- 2.2 Netty服务端收发数据实现
- 2.2.1 服务端处理器
- 2.2.2 通道初始化
- 2.2.3 netty服务端
- 2.3 单元测试
一、前言介绍
💡 介绍服务端接收数据后,通过 writeAndFlush 发送 ByteBuf 字节码向客户端传输信息。
因为我们使用客户端模拟器的编码是 GBK 格式,否则会乱码。
二、代码实现
2.1 工程结构
netty-1.0-05
|-src
|-main
|-java
|-com.lino.netty.server
|-MyChannelInitializer.java
|-MyServerHandler.java
|-NettyServer.java
2.2 Netty服务端收发数据实现
2.2.1 服务端处理器
MyServerHandler.java
package com.lino.netty.server;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import java.time.LocalDateTime;
import java.util.Date;
/**
* @description: 服务端处理器
*/
public class MyServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
SocketChannel channel = (SocketChannel) ctx.channel();
System.out.println("链接报告开始");
System.out.println("链接报告信息:有一客户端链接到本服务端");
System.out.println("链接报告IP:" + channel.localAddress().getHostString());
System.out.println("链接报告Port:" + channel.localAddress().getPort());
System.out.println("链接报告完毕");
// 通知客户端连接建立成功
String str = "通知客户端链接建立成功" + " " + new Date() + " " + channel.localAddress().getHostString() + "\r\n";
ByteBuf buf = Unpooled.buffer(str.getBytes().length);
buf.writeBytes(str.getBytes("GBK"));
ctx.writeAndFlush(buf);
}
/**
* 当客户端主动断开服务端的链接后,这个通道就是不活跃的。
* 也就是说客户端与服务端的关闭了通信通道并且不可以传输数据。
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端断开链接" + ctx.channel().localAddress().toString());
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 接收msg消息
System.out.println(LocalDateTime.now() + " 接收到消息:" + msg);
// 通知客户端链接消息发送成功
String str = "服务端收到:" + new Date() + " " + msg + "\r\n";
ByteBuf buf = Unpooled.buffer(str.getBytes().length);
buf.writeBytes(str.getBytes("GBK"));
ctx.writeAndFlush(buf);
}
/**
* 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
System.out.println("异常信息:\r\n" + cause.getMessage());
}
}
2.2.2 通道初始化
MyChannelInitializer.java
package com.lino.netty.server;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import java.nio.charset.Charset;
/**
* @description: 通道初始化
*/
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel channel) {
// 解码转String,注意调整自己的编码格式 GBK,UTF-8
channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
// 在管道中添加接收数据实现方法
channel.pipeline().addLast(new MyServerHandler());
}
}
2.2.3 netty服务端
NettyServer.java
package com.lino.netty.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
/**
* @description: netty服务端
*/
public class NettyServer {
public static void main(String[] args) {
new NettyServer().bind(7397);
}
/**
* 开启链接
*
* @param port 端口
*/
private void bind(int port) {
// 配置服务端NIO线程组
// NioEventLoopGroup extends MultithreadEventLoopGroup
// Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
EventLoopGroup parentGroup = new NioEventLoopGroup();
EventLoopGroup childGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(parentGroup, childGroup)
// 非阻塞模式
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 128)
.childHandler(new MyChannelInitializer());
ChannelFuture future = b.bind(port).sync();
System.out.println("lino-learn-netty server start done.");
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
childGroup.shutdownGracefully();
parentGroup.shutdownGracefully();
}
}
}
2.3 单元测试
启动NettyServer
lino-learn-netty server start done.
链接报告开始
链接报告信息:有一客户端链接到本服务端
链接报告IP:192.168.80.1
链接报告Port:7397
链接报告完毕
2023-02-18T14:32:51.321 接收到消息:你好,netty服务端!
2023-02-18T14:32:52.063 接收到消息:你好,netty服务端!
2023-02-18T14:32:52.607 接收到消息:你好,netty服务端!
2023-02-18T14:32:53.391 接收到消息:你好,netty服务端!
客户端断开链接/192.168.80.1:7397
网络调试助手