Article Directory
A basic idea
Read and write logic processing stages are started by adding to the logic processing chain Pipeline logical processor to read and write data in the logical connection.
-
Client connection success logic processor callback
channelActive()
method -
The client and server receives data back to the calling of each other's logic processor
channelRead()
method. -
The client and server to write data to the other call
writeAndFlush()
method -
Binary data transmission carrier client and server interaction is
ByteBuf
II. Communication Process
III. Code implementation
- NIOServer
/**
* @Auther: ARong
* @Description: 服务端-客户端双向通信,服务端在接收到客户端信息后向客户端发出响应
*/
public class NIOServer {
public static void main(String[] args) {
ServerBootstrap serverBootstrap = new ServerBootstrap();
NioEventLoopGroup bossGroup = new NioEventLoopGroup(); // 监听组
NioEventLoopGroup workerGroup = new NioEventLoopGroup(); // 工作组
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) //NIO模式
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
// 初始化channel
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new FirstServerHandler());
}
}).bind(8000);
}
}
- NIOClient
/**
* @Auther: ARong
* @Description: 服务端-客户端双向通信,客户端向服务端发送信息
*/
public class NIOClient {
public static void main(String[] args) throws InterruptedException {
Bootstrap bootstrap = new Bootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// 责任链模式,添加第一次连接的客户端处理逻辑
ch.pipeline().addLast(new FirstClientHandler());
}
});
Channel channel = bootstrap.connect("127.0.0.1", 8000).channel();
String message = String.format("HelloWorld From %s", new SimpleDateFormat("hh:mm:ss").format(new Date()));
channel.writeAndFlush(message);
}
}
- FirstServerHandler
/**
* @Auther: ARong
* @Description: 服务端被首次连接的处理逻辑
*/
public class FirstServerHandler extends ChannelInboundHandlerAdapter {
@Override
/*
* @Author ARong
* @Description 接收到服务端消息时触发
* @Param [ctx, msg]
* @return void
**/
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println(String.format("服务端读取到数据%s From %s",
byteBuf.toString(Charset.forName("utf-8")),
getCurTime()));
ByteBuf byteBuf1 = getByteBuf(ctx);
ctx.channel().writeAndFlush(byteBuf1);
}
/*
* @Author ARong
* @Description 获取二进制抽象 ByteBuf
* @Param [ctx]
* @return io.netty.buffer.ByteBuf
**/
private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
// 获取二进制抽象 ByteBuf
ByteBuf buffer = ctx.alloc().buffer();
// 准备数据,指定字符串的字符集为 utf-8
String response = String.format("服务端返回HelloWorld From %s", getCurTime());
byte[] bytes = response.getBytes(Charset.forName("utf-8"));
// 填充数据到 ByteBuf
buffer.writeBytes(bytes);
return buffer;
}
private String getCurTime() {
return new SimpleDateFormat("hh:mm:ss").format(new Date());
}
}
- FirstClientHandler
/**
* @Auther: ARong
* @Description: 首次连接的客户端处理逻辑
*/
public class FirstClientHandler extends ChannelInboundHandlerAdapter {
@Override
/*
* @Author ARong
* @Description 客户端与服务端首次连接的处理逻辑
* @Param [ctx]
* @return void
**/
public void channelActive(ChannelHandlerContext ctx) throws Exception {
// 编码数据
ByteBuf byteBuf = getByteBuf(ctx);
// 写回给服务端
ctx.channel().writeAndFlush(byteBuf);
}
@Override
/*
* @Author ARong
* @Description 接收到服务端消息时触发
* @Param [ctx, msg]
* @return void
**/
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf) msg;
System.out.println(String.format("客户端读取到数据%s From %s",
byteBuf.toString(Charset.forName("utf-8")),
getCurTime()));
}
/*
* @Author ARong
* @Description 获取二进制抽象 ByteBuf
* @Param [ctx]
* @return io.netty.buffer.ByteBuf
**/
private ByteBuf getByteBuf(ChannelHandlerContext ctx) {
// 获取二进制抽象 ByteBuf
ByteBuf buffer = ctx.alloc().buffer();
// 准备数据,指定字符串的字符集为 utf-8
String response = String.format("客户端返回HelloWorld From %s", getCurTime());
byte[] bytes = response.getBytes(Charset.forName("utf-8"));
// 填充数据到 ByteBuf
buffer.writeBytes(bytes);
return buffer;
}
private String getCurTime() {
return new SimpleDateFormat("hh:mm:ss").format(new Date());
}
}
In turn starts the client and server, two-way communication: