说明
使用Netty框架编程,当Channel将数据发送成功以后,存放发送数据的ByteBuf会被自动释放。
为了进行验证,我们可以在发送数据前,通过io.netty.buffer.ByteBuf的refCnt()函数看看引用计数,通过Channel发送成功以后再看看引用计数,对比下。
示例
为了突出重点,此处只给出代码片段。
package com.thb.power.terminal;import java.io.BufferedReader;
import java.io.InputStreamReader;import com.thb.power.packet.register.RegisterRequestPacket;import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;/*** 客户端主函数* @author thb**/
public class Terminal {// 要连接的服务端的host static final String HOST = System.getProperty("host", "127.0.0.1"); // 要连接的服务端的端口号 static final int PORT = Integer.parseInt(System.getProperty("port", "22335"));public static void main(String[] args) throws Exception {// 配置客户端EventLoopGroup group = new NioEventLoopGroup();try {Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new TerminalInitializer());// 启动客户端Channel ch = b.connect(HOST, PORT).sync().channel();//System.out.println("channel: " + ch.getClass().getName());ChannelFuture lastWriteFuture = null;BufferedReader in = new BufferedReader(new InputStreamReader(System.in));System.out.println("please input(register):");for (;;) {String line = in.readLine();if (line == null) {break;} // 如果用户输入register,表示命令客户端发送注册请求给服务器if (line.toLowerCase().equals("register")) {RegisterRequestPacket registerRequest = new RegisterRequestPacket();// 返回的ByteBuf存放着注册请求的数据ByteBuf buf = registerRequest.build(ch);// 发送数据前,看看引用计数System.out.println("before write and flush, buf.refCnt(): " + buf.refCnt());lastWriteFuture = ch.writeAndFlush(buf);lastWriteFuture.addListener(new ChannelFutureListener() {public void operationComplete(ChannelFuture future) {// 发送数据成功以后,再看看引用计数System.out.println("after write and flush completed, buf.refCnt(): " + buf.refCnt());}});}}if (lastWriteFuture != null) {lastWriteFuture.sync();}} finally {// 关闭event loop以便终止所有的线程group.shutdownGracefully();}}}// ChannelInitializer的子类
package com.thb.power.terminal;import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;public class TerminalInitializer extends ChannelInitializer<SocketChannel> {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ChannelPipeline p = ch.pipeline();p.addLast(new LoggingHandler(LogLevel.INFO));}
}
运行输出结果:
从上面输出的打印信息可以看出,发送数据前,引用计数是1,发送数据成功后,引用计数变为0,被释放了。