大家好,请帮帮忙,看看这个是什么意思?

hellonetty 发布于 2016/02/26 22:05
阅读 375
收藏 0
private static final byte[] LENGTH_PLACEHOLDER = new byte[4];

void encode(Object msg, ByteBuf out) throws Exception {
    try {
        int lengthPos = out.writerIndex(); //这一个获得一个int数值,这个数值代表什么?
        out.writeBytes(LENGTH_PLACEHOLDER); //为什么要往out里面写入一个byte[4]数组? 是不是为了存储msg对象?
        ChannelBufferByteOutput output = new ChannelBufferByteOutput(out);
        marshaller.start(output);
        marshaller.writeObject(msg);
        marshaller.finish();
        out.setInt(lengthPos, out.writerIndex() - lengthPos - 4); //这一句不懂,请指点。
    } finally {
        marshaller.close();

    }




也许大家会对我说,为什么不看API文档,其实我看了,但是还是不太理解,请给我指点下。万分感激各位。

 

public abstract int writerIndex()

Returns the writerIndex of this buffer 

public abstract ByteBuf writeBytes(byte[] src)

 Transfers the specified source array's data to this buffer starting at the current writerIndex and increases the writerIndex by the number of the transferred bytes (= src.length).

public abstract ByteBuf setInt(int index,
             int value)
Sets the specified 32-bit integer at the specified absolute index in this buffer. This method does not modify  reader Index or writerIndex of this buffer.
 


加载中
0
xpbob
xpbob
你的api好像不是java se的,但是nio思想还是一样的,nio的buffer是一段区域,我们假设为数组长度为7,且你有一个数据,自此你的写指针在1号位置,writerIndex()返回的就是1,writeBytes就是就是把你的数组内容写入,此时buffer里的数组就有5个数了,写的位置就在5上(因为还有0位置),此时调用writerIndex就是5,setint就是在特定的位置设置特定的值,lengthPos就是你原来最初可写的位置,现在往这个位置上写out.writerIndex() - lengthPos -4,但是我并不知道你marshaller是怎么写的数据,我猜测,是写了对象进去,然后out.writerIndex() - lengthPos -4,实际就是你对象的长度,而你刚开始留的那四个byte位置是用来写对象长度的,因为Int正好是4个字节,所以你对象的格式就是对象长度+对象内容
hellonetty
hellonetty
回复 @xpbob : 我也是刚接触,哈哈,一边查资料一边学习。
xpbob
xpbob
@hellonetty 惭愧了,虽然我做javase开发,但我真没用过netty,基本上一直都是借助java标准api
hellonetty
hellonetty
回复 @xpbob : netty 和 jboss marshalling, bytebuf是netty的API , marshaller这个是Jboss marshalling里面的org.jboss.marshalling.Marshaller的对象。
xpbob
xpbob
@hellonetty 没事,我也是一边看一边猜的,你给的代码不全,熟悉nio还是能猜到的,但是我很好奇,你这是什么api,se里没有啊
hellonetty
hellonetty
回复 @xpbob : 非常的感谢,你这么一说真是豁然开朗,谢谢,谢谢。
下一页
1
kakai
kakai
private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
 
void encode(Object msg, ByteBuf out) throws Exception {
    try {
        int lengthPos = out.writerIndex(); //获取字节缓冲区最终的写入位置
        out.writeBytes(LENGTH_PLACEHOLDER); //四个字节表示一个int型数据,用于表示数据包内容长度,此时还不知道写入了多少个字节,仅用于占位
        ChannelBufferByteOutput output = new ChannelBufferByteOutput(out);
        marshaller.start(output);
        marshaller.writeObject(msg);
        marshaller.finish();
        out.setInt(lengthPos, out.writerIndex() - lengthPos - 4); //先前占位的4个字节被正式写入,写入的值为msg的字节长度(int类型)
    } finally {
        marshaller.close();
 
    }
hellonetty
hellonetty
非常感谢,你的回复让我有了更深的认识。
0
ddatsh
ddatsh
学习NIO先
0
kakai
kakai

这种写法跟netty无关,socket字节通信中自定义数据包格式很多都是用这种

数据包内容长度+数据包内容字节

其中数据包内容长度一般为4个字节,如果估算的数据包内容都不会太大可以用short型2个字节,这几个字节是用于粘包解码的

0
kakai
kakai
为什么涉及到粘包解码呢?因为socket中一次性收到的数据不一定是完整的一个数据包,有可能刚好一个数据包,有可能半个数据包、一个数据包再多点字节、两个或多个数据包、两个或多个数据包再多点字节,这些情况就要在循环中使用数据包长度做粘包解码的处理。
0
wenhaoran
wenhaoran
netty 权威指南 lilinfeng的吗?
返回顶部
顶部