处理二进制包

时间:2016-05-24 21:43:27

标签: java networking

我对这个数据包处理程序进行了编码,但我可以想象它会陷入困境或者无法读取不完整数据的情况。我的问题是:

  1. 我应该使用两个缓冲区,一个用于当前传入数据,另一个用于将不完整数据附加到?
  2. 我愚蠢地过于复杂?
  3. 代码:

    byte[] buffer;
    int bufferLength;
    int bytesRead;
    
    buffer = new byte[1024];
    
    while (bluetoothConnected) {
        try {
            // Wait for packet header
            if (mmInStream.available() >= 8) {
                bufferLength = mmInStream.read(buffer);
                bytesRead = 0;
    
                // Parse every packet
                while (true) {
                    int commandType = ByteBuffer.wrap(buffer, 0, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();
                    int payloadSize = ByteBuffer.wrap(buffer, 2, 2).order(ByteOrder.LITTLE_ENDIAN).getShort();
                    int packetSize = PACKET_HEADER_SIZE + payloadSize;
    
                    // Break if payload is incomplete
                    if (bufferLength < (bytesRead + packetSize)) {
                        // Append to other buffer
                        break;
                    }
    
                    byte[] packet = new byte[packetSize];
                    System.arraycopy(buffer, bytesRead, packet, 0, packetSize);
    
                    parsePacketSequence(socket, packet);
                    bytesRead += packetSize;
    
                    // Break if all bytes are read
                    if (bufferLength == bytesRead)
                    {
                        break;
                    }
    
                    // Break if more bytes are needed
                    // Packet header incomplete
                    if ((bufferLength - bytesRead) < PACKET_HEADER_SIZE)
                    {
                        // Append to other buffer
                        break;
                    }
                }
            }
        } 
        catch (IOException e) {
            bluetoothConnected = false;
            Log.d(TAG, "Error " + e);
            break;
        }
    }
    

1 个答案:

答案 0 :(得分:1)

  
      
  1. 我应该使用两个缓冲区,一个用于当前传入数据,另一个用于将不完整数据附加到?
  2.   

没有

  
      
  1. 我愚蠢地过于复杂?
  2.   

这是使用DataInputStream的简单版本:

DataInputStream din = new DataInputStream(mmInStream);

while (bluetoothConnected) {
    try {
        // Read packet header
        int commandType = swap(din.readShort());
        int payloadSize = swap(din.readShort());
        int packetSize = PACKET_HEADER_SIZE + payloadSize;
        byte[] packet = new byte[packetSize];
        din.readFully(packet);
        parsePacketSequence(socket, packet);
    } 
    catch (IOException e) {
        bluetoothConnected = false;
        Log.d(TAG, "Error " + e);
        break;
    }
}

将一个简短的litte-endian字节顺序转换为Java字节顺序的swap()方法留给读者练习。

请注意,parsePacketSequence()如果不知道commandType,我就不知道如何工作。

E&安培; OE