2011-06-06 48 views
3

我正在一个项目中,我需要读取一些值并通过套接字连接发送。 这是我必须创建包的格式: enter image description hereJava:如何使用字节创建包?

我必须读取这些值(我不知道它必须是一个王类型的每个值,int或字符串等): 型:的操作(如何获得4位只?) reserverd:我会填写0的 来源:谁发送消息 接收方:谁将接收消息 算法:哪种算法是goona被用来加密消息 填充:在加密算法中使用它 模式:要加密的模式

我必须读取此值并创建必须只有7个字节的程序包。

我该怎么做?

它必须是这样的,我认为:

byte[] r = new byte[]{ 
       type+reserverd, 
       origin_1_byte, origin_2_byte, 
       receiver_1_byte, receiver_2_byte, 
       algorithm+padding, 
       mode}; 

UPDATE:

ByteBuffer buffer = ByteBuffer.allocate(100); 
// read data into buffer 
buffer.rewind(); 
buffer.order(ByteOrder.LITTLE_ENDIAN); 
// 0xf and co mask off sign extension -> handle byte as unsigned 
int type = (buffer.get() >> 4) & 0xf; // 15 in decimal 

buffer.rewind(); 
buffer.put((byte)(type << 4)); 
System.out.println("type = " + type); 


output : 0 (why ?) 

任何想法?

+0

请将您从网络读取数据的代码添加到ByteBuffer中。看起来好像你试图读取从未存储在bytebuffer中的数据 - 这显然无法工作;) – Voo 2011-06-06 19:07:16

+0

Dude,这似乎很难..对不起,我是一个新的Java,所以我不怎么发送这个以及如何在我的服务器套接字中接收这个。 我用我的clint发送printStream,并用bufferedReader接收..抱歉的人,我不想打扰你。 – 2011-06-06 19:31:24

+0

没有概率,没有概率 - 每个人都开始新的。可能最好的想法是在这里为java NIO包阅读一个像[this]这样的快速教程(http://java.sun.com/developer/technicalArticles/releases/nio/),它在一小段中解释了基本知识工作。我会将重要的部分添加到我的答案中。 – Voo 2011-06-06 19:33:31

回答

2

只需使用ByteBuffer和nio包。这样你就可以轻松地从网络上读取数据,不必担心Endianess(这很重要!如果你使用流,你几乎必须实现自己的转移 - 尽管这可能是一个很好的练习)。不要忘记将缓冲区的字节顺序设置为正确的值。我们在内部使用int,因为a)所有数学运算无论如何返回整数,并且b)您能够将值作为无符号处理。

ByteBuffer buffer = ByteBuffer.allocate(100); 
    // read data into buffer 
    buffer.rewind(); 
    buffer.order(ByteOrder.LITTLE_ENDIAN); 
      // 0xf and co mask off sign extension -> handle byte as unsigned 
    int type = (buffer.get() >> 4) & 0xf; 
    int origin = buffer.getShort() & 0xffff; 
    int receiver = buffer.getShort() & 0xffff; 
    // and so on 

写入数据备份你很可能反过来做:

ByteBuffer buffer = ByteBuffer.allocate(100); 
    buffer.rewind(); 
    buffer.put((byte)(type << 4)); 
    buffer.putShort((short)origin); 
    // and so on 

编辑: 通常你会直接读取数据从网络通道字节缓冲区和使用Java NIO包。快速教程是here。但既然你已经有了Socket,我们会让它更容易一些。请注意,我忽略了所有错误检查的不足之处。使用OutputStream和WritableByteChannel(写入)可以在另一个方向上工作。

InputStream is = socket.getInputStream(); 
ReadableByteChannel source = Channels.newChannel(istream); 
ByteBuffer buffer = ByteBuffer.allocateDirect(headerSize); 
source.read(buffer); 
// now header is in buffer and can be used as seen above. 
+0

感谢您的帮助,但我没有再次获得原始值。 – 2011-06-06 18:43:05

+0

@Valter那么你究竟会得到什么价值?首先确保在第一个位置读取buffer.get()返回一个包含正确数据的字节(type | reserved)。如果情况并非如此,那么在你读取数据之前,问题就在于此。发布一个包含ByteBuffer代码的新问题(包括从网络/文件中读取数据的部分)可能是最好的想法。 – Voo 2011-06-06 18:55:23

+0

我更新我的帖子并尝试你的例子,请看看。 – 2011-06-06 19:03:49

0

看看ByteBuffer

还要考虑位操作,比如“移位”。如果您需要将3存储到type和7存储到reserved,那么您只需要通过移位将它们存储到8位,即byte

byte typeReserved = (3 << 4) | 7; 

想要获得价值吗?

byte type = (typeReserved >> 4) & 0xF; 
byte reserved = typeReserved & 0xF; 
0

我使用字节有同样的问题,我也发现,在Java中没有“无符号字节”,所以字节值只会从-128到127,如果我是正确的。我被限制使用短裤,就好像它们是字节一样,所以我可以使用高达255的值。

我敢肯定有出路,虽然,但当时我只是没有足够的时间来弄明白

+0

在内部使用整数并掩盖符号扩展名。唯一有问题的数据类型是无符号64位值,您几乎必须使用BigInteger。 – Voo 2011-06-06 17:39:51

0

你会使用位移位(使用<<)和位ORS(使用|

new byte[]{ 
      type<<4|reserverd, 
      origin_1_byte, origin_2_byte, 
      receiver_1_byte, receiver_2_byte, 
      algorithm<<4 | padding, 
      mode}; 

提取它们,你需要口罩和移位(buff[0]&0xf0)>>>4将提取例如型)

0

ByteBuffer,而在其他的答案,或者DataOutputStream联合建议。