缓冲区
在而向流的IO中,可以将数据直接写入或者将数据直接读到Stream 对象中.
在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的,在写入数据时,写入到缓冲区中. 任何时访问NIO 中的数据都是通过缓冲区进行操作。
socketchannel本身应该有缓存,它的缓存主要是在TCP的初始化的时候建立。
ByteBuf的缓冲区:
堆内存
直接内存
从ChannelRead之后,有无队列?
ChannelRead之后,是如何到ByteBuffer中,如果没有取,缓冲区的结果会如何?
缓冲区是TCP配置的时候,定义的缓冲区吗?这个缓冲区会被堆回收吗?我估计不会被堆栈回收。不在堆栈之内。
sc.read(readBuffer);这个可能是把socket的内容,读入到readBuffer中。
如果剩余空间不足,那么就会需要重新创建一个新的ByteBuffer,并将之前的ByteBuffer复制到新的创建的 ByteBuffer中。
时于使用者而言I 不需要关心底层的校验和扩展细节,只要不超过设置的最大缓冲区容量即可(应该是TCP缓冲区的尺寸)
,11 比于其他的l ava 时忽绩冲区的分配和将版盐个挺时的操作. 因此. 我们需要尽量重用官们J .由于缓忡区的功志扩张需要址行字节盘组的直制, 它是个托时的悻作1 因此,为丁耻大程匪地提升性能,往往fA: 要思耻大努力提升!11忡区的重用率.
从 SocketChannel 读取数据
第一种方法
要从SocketChannel中读取数据,调用一个read()的方法之一。以下是例子:
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = socketChannel.read(buf);
首先,分配一个Buffer。从SocketChannel读取到的数据将会放到这个Buffer中。
然后,调用SocketChannel.read()。该方法将数据从SocketChannel 读到Buffer中。read()方法返回的int值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。
第二种方法
正常的读的方式方法是 buffer.put(value.getBytes());调用put的方法,但是在Socket就用上面的方法
第三种方法
接受msg,然后进行实例化
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
byte[] req =new byte[buf.readableBytes()];
buf.readBytes(req);
String body =new String(req, "UTF-8");
System.out.println("The time server receive order : " + body);
接收过来的msg也可能是其他类型?
如这个例子 instanceof ByteBuf。
书中表示,如果不是这个类型,那么才需要解码,否则直接进行透传。
在这个方法中
public abstract class ByteToMessageDecoderextends ChannelInboundHandlerAdapter {
public void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {
if (msginstanceof ByteBuf) { 。。。
else {
ctx.fireChannelRead(msg);
}
那么最终的结果:
那些不属于ByteBuf,有intbuf等
2019年6月23日
Netty自己定义的handle,会自动在解码后,将消息传递到下一个环节。
如果用户定义的handle,就需要把消息自己传递到下一个环节。