客户端发送数据至服务端
示例代码Client.java
/**
* @program: learnnetty
* @description: 客户端发送数据
* @create: 2020-05-04 10:31
**/
public class Client {
public static void main(String[] args) {
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap
.group(workerGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel
.pipeline()
.addLast(new ClientHandler());
}
});
bootstrap.connect("127.0.0.1", 8080);
}
}
上述代码中:
SocketChannel.pipline()
返回的是这条连接的相关逻辑处理链,采用的是责任链的设计模式;- 通过调用
SocketChannel.pipline().addLast()
给处理链添加一个逻辑处理器;
示例代码ClientHandler.java
/**
* @program: learnnetty
* @description: 业务处理
* @create: 2020-05-04 10:39
**/
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(new Date() + " 客户端写出数据");
ByteBuf buffer = getByteBuf(ctx, "这是客户端");
ctx.channel().writeAndFlush(buffer);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
ByteBuf byteBuf = ctx.alloc().buffer();
byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
byteBuf.writeBytes(bytes);
return byteBuf;
}
}
上述代码中:
- 自定义的逻辑处理器需要继承
ChannelInboundHandlerAdapter
类,并重写channelActive()
方法,此方法会在客户端建立连接成功后被调用; - 在成功连接后,调用
channelActive()
方法时自定义的逻辑处理器就会发挥作用; - 自定义的逻辑处理器处理业务分为两步:
- 获取Netty对二进制数据的抽象ByteBuf,示例代码中通过
ChannelHandlerContext.alloc()
获取到一个ByteBuf的内存管理器,此内存管理器就是分配一个ByteBuf; - 将字符串按照指定的字符集转换为二进制数据并填充至
ByteBuf
中,之后再调用ChannelHandlerContext.channel().writeAndFlush()
把数据写出;
- 获取Netty对二进制数据的抽象ByteBuf,示例代码中通过
服务端读取客户端数据
示例代码Server.java
/**
* @program: learnnetty
* @description: 服务端
* @create: 2020-05-04 10:54
**/
public class Server {
public static void main(String[] args) {
NioEventLoopGroup workerGroup = new NioEventLoopGroup();
NioEventLoopGroup bossGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
nioSocketChannel
.pipeline()
.addLast(new ServerHandler());
}
});
serverBootstrap.bind(8080);
}
}
示例代码ServerHandler.java
/**
* @program: learnnetty
* @description: 服务端处理
* @create: 2020-05-04 10:54
**/
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf)msg;
System.out.println(new Date() + " :服务端收到:" + byteBuf.toString(StandardCharsets.UTF_8));
}
}
在上述代码中:
服务端输出:
Mon May 04 11:01:19 CST 2020 :服务端收到:这是客户端
客户端输出:
Mon May 04 11:01:19 CST 2020 客户端写出数据
服务端返回数据给客户端
修改后的ServerHandler.java
/**
* @program: learnnetty
* @description: 服务端处理
* @create: 2020-05-04 10:54
**/
public class ServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//读取数据
ByteBuf byteBuf = (ByteBuf)msg;
System.out.println(new Date() + ",服务端收到:" + byteBuf.toString(StandardCharsets.UTF_8));
//给予反馈
System.out.println(new Date() + ",服务端写出数据");
ByteBuf buff = getByteBuf(ctx, "服务端已收到信息");
ctx.channel().writeAndFlush(buff);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
ByteBuf buf = ctx.alloc().buffer();
buf.writeBytes(bytes);
return buf;
}
}
修改后的ClientHandler.java
/**
* @program: learnnetty
* @description: 业务处理
* @create: 2020-05-04 10:39
**/
public class ClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf byteBuf = (ByteBuf)msg;
System.out.println(new Date() + ",客户端收到来自服务端的反馈:" + byteBuf.toString(StandardCharsets.UTF_8));
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println(new Date() + " 客户端写出数据");
ByteBuf buffer = getByteBuf(ctx, "这是客户端");
ctx.channel().writeAndFlush(buffer);
}
private ByteBuf getByteBuf(ChannelHandlerContext ctx, String msg){
ByteBuf byteBuf = ctx.alloc().buffer();
byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
byteBuf.writeBytes(bytes);
return byteBuf;
}
}
服务端输出:
Mon May 04 11:07:52 CST 2020,服务端收到:这是客户端
Mon May 04 11:07:52 CST 2020,服务端写出数据
客户端输出:
Mon May 04 11:07:52 CST 2020 客户端写出数据
Mon May 04 11:07:52 CST 2020,客户端收到来自服务端的反馈:服务端已收到信息