发送序列化数据时丢失信息

时间:2014-06-03 21:04:52

标签: java byte

我在java中遇到网络问题。这可能是因为我习惯于操作字节,这是由于某些原因用Java签名(我把它作为最终邪恶存在的证明)。

我一直在努力使用某些数据包系统发送二进制数据。最初,我想自己创建数据,但Java并不是设计用于字节操作。相反,建议您发送序列化对象。

所以我查找了如何创建一个{} {}} ChatPacket,我将通过网络发送。

我的代码来自与上面链接的答案类似的答案(我找不到原来的答案):

//Convert packet to raw data
public byte[] getBytes() {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutput out = null;
    try {
      //Pass the stream refference to the weird object output stream thing
      out = new ObjectOutputStream(bos);
      //Save the packet into byte stream
      out.writeObject(this);
      //Create separate arrays of bytes
      byte[] data = bos.toByteArray();     
      //Funny way to convert int in array of 4 bytes. The Java Way...
      byte[] size = ByteBuffer.allocate(4).putInt(data.length).array();
      //The final data array - feel free to sugest more efficient way to merge the two arrays
      byte[] data_all = new byte[data.length+4];
      //Merge the arrays of bytes - I found no other way than creating third array.
      for(int i=0; i<data_all.length; i++) {
          //Save the size
          if(i<4) {
             data_all[i] = size[i];
          }
          //Save the data
          else {
             data_all[i] = data[i-4];  
          }
      }
      //Debug output
      Log.debug("Sending packet of "+data.length+" bytes");
      for(int i=0; i<data_all.length; i++) {
          Log.debug(i+": Sending character: "+((char)data_all[i]))+" ["+(int)data_all[i]+"]");
      }

现在最后的调试行产生了一个很好的输出:

Sending packet of 262 bytes
0: Sending character: 0 [0]     -  
1: Sending character: 0 [0]     |  The int - size of the packet
2: Sending character: 1 [1]     |
3: Sending character: 6 [6]     -
4: Sending character: -84 [-84] -
5: Sending character: -19 [-19] |
6: Sending character: 0 [0]     |  The data generated within the serialisation function
7: Sending character: 5 [5]     |
8: Sending character: 115 [115] |
9: Sending character: 114 [114] ...
10: ...

有数字而不是实际的字符。请原谅我 - 我在添加代码后修复了这个函数并且懒得重写它。

到目前为止一切顺利。现在让我们看看另一方面到底是什么。我在循环中接收数据,我在一些缓冲流上调用read方法:

while((character=in.read())!=-1) 
    ...

我已经创建了一个非常类似的输出,你可以看到它,只是它现在打印收到的数据。

1: Received character: \0 [0] -
2: Received character: \0 [0] |  The size again
3: Received character:  [1]   |
4: Received character:  [6]   -
Expecting 262 bytes of data!     -
1: Received character: � [65533] |
2: Received character: � [65533] | The serialised data...
3: Received character: \0 [0]    |
4: Received character:  [5]     ...
5: ...

正如你所看到的,负数不是溢出或类似的东西,而是以某种方式变成了巨大的价值 我可以看到实际上通过网络发送的是什么 - 我一直在询问这个问题但是答案真的没有帮助,正如你所看到的那样。

基本上我现在的问题是:

  1. 如何可能,负值可以作为字节通过网络传递 - 除非它们在发送时已经损坏...
  2. 我如何收到这些值 - 上面调试中的值由read方法...
  3. 返回

    最后,我需要重新调整字节数组。所以我还需要将可以松散地转换为字节的值。

    private List<Byte> buffer = new ArrayList<>();
    public boolean receiveChar(int current) {
        buffer.add((byte)current);
        ... some stuff
    }
    

0 个答案:

没有答案