简体   繁体   中英

ChannelBuffer readInt()/writeInt() results in wrong value

I have server implementation in Java using Netty and client is in Adobe Flash.

When I am sending the request or response in the buffer, I am first writing the length of the buffer and then the data. I am writing the length of the data using ChannelBuffer.writeInt() in the server side and ByteArray.writeInt() in the client side and then reading it on the other side using ByteArray.readInt() for client and ChannelBuffer.readInt() for server. But I get a wrong value for both of them.

My question is, is there a difference when I do a ChannelBuffer.writeInt() / ChannelBuffer.readInt() in java and do a corresponding ByteArray.readInt() / ByteArray.writeInt() in Adobe Flash actionscript. If yes, please tell me what is it and how to make it work.

I have tried to do some bit shifting operation to make it work, but it doesn't work. Is this dependent on Endianess ? If yes, how ? If it is not dependent, then is there anything on which this might be dependent ?

Thanks

haraldK is exactly right. When an integer is written out across the network (or technically, when it is serially written), the bytes are received in the opposite order. Using netty channel buffers (and groovy) this script makes it a bit easier what's going on. It starts with an int of 5 and writes to a LITTLE_ENDIAN buffer. The contents of that buffer are then copied into a BIG_ENDIAN buffer, and when read back out, present and int which os not 5. The underlying bytes of the int have been reversed. The script also prints the binary (bits) representation of the int, and, using a much more efficient transformation, Integer.reverseBytes(int) , does the same thing.

import org.jboss.netty.buffer.*;
import java.nio.*;

lBuff = ChannelBuffers.buffer(ByteOrder.LITTLE_ENDIAN, 4);
int a = 5;
lBuff.writeInt(a);
bBuff = ChannelBuffers.buffer(ByteOrder.BIG_ENDIAN, 4);
bBuff.writeBytes(lBuff);
int b = bBuff.readInt();
binString = Integer.toBinaryString(b);
println "Int: $b  ($binString), Reversed: ${Integer.reverseBytes(b)}";
lBuff.clear(); bBuff.clear();
lBuff.writeInt(b);
bBuff.writeBytes(lBuff);
b = bBuff.readInt();
println "Int: $b  (${Integer.toBinaryString(b)}), Reversed: ${Integer.reverseBytes(b)}";

The output is as follows:

Int: 83886080  (101000000000000000000000000), Reversed: 5 
Int: 5 (101), Reversed: 83886080

I don't know much about actionscript-3, but this link outlines how to swap endianess of a value in JavaScript:

function swap32(val) {
    return ((val & 0xFF) << 24)
           | ((val & 0xFF00) << 8)
           | ((val >> 8) & 0xFF00)
           | ((val >> 24) & 0xFF);
}

Output:

> swap32(5)
> 83886080
> swap32(83886080)
> 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM