java - InputStream 读取源中不存在的额外字节

标签 java sockets stream byte inputstream


我有一个 Java 服务器,用于接收从客户端应用程序发送的 RTMP 数据包。服务器使用InputStream读取数据包头,识别数据包主体有多大,然后使用以下命令创建字节数组大小,然后从该数组中的InputStream读取该body
问题是:接收到的字节集被修改 - 有必要的字节(存在于源中)与源数据包中不存在的额外字节(我通过 WireShark 观察源数据包的内容,并将它们与我在服务器上收到的字节进行比较)。
这些额外的字节是 0xc6 字节,顺便说一下,它们定期相遇......
它看起来像这样:
来源:... 75 f1 f5 55 73 .... fc a9 47 14 ... 40 ca d5 75 ... fe 30 a7
收到:... 75 f1 f5 55 73 c6 .... fc a9 47 14 c6 ... 40 ca d5 75 c6 ... fe 30 a7
... - 表示“这里有一定数量的字节”
结果,我无法接收必要的数据,因为它被拉伸(stretch)了,比我从 rtmp header 收到的 body size 更大。最重要的是,修改后的数据不是我必须接收的!
我的问题是:如何解决? InputStream 有什么问题?为什么它会将这些 0xc6 字节插入到接收数组中?
我知道我可以简单地解析接收到的数组并排除那些额外的字节,但这是一个糟糕的解决方案,因为速度和性能是必要的(并且,在这种情况下,不清楚它是来自源的额外字节还是字节,没有比较整个数组)...

enter code here
public static void getRtmpPacket(InputStream in) throws Exception {

    byte[] rtmpHeader = new byte[8];
    byte[] rtmpBody;
    int bodySize = 0;

    //reading rtmp header:
    in.read(rtmpHeader);
    //reading the body size. This method works fine
    bodySize = Server.bigEndianBytesToInt(rtmpHeader, 4, 3);
    rtmpBody = new byte[bodySize];
    in.read(rtmpBody);
    //printing received data:
    System.out.println("Packet:");
    System.out.println("Body size: " + bodySize);
    System.out.print(bytesToString(rtmpHeader) + " ");
    System.out.print(bytesToString(rtmpBody));
    System.out.println();

}

最佳答案

根据 RTMP 规范,它的行为正常。您需要对传入的数据进行“分块”,因此在单个 read() 中一次性读取所有数据是行不通的。

沿着这些思路(伪代码):

int remaining = payloadSize;
int totalRead = 0;
int totalReadForChunk = 0;
while (true) {
  int num = read(buf, 0, min(remaining, chunkSize - totalReadForChunk))
  if (num < 0) break;  // i/o error
  appendData(<buf>, 0, num)
  totalReadForChunk += num
  remaining -= num
  if (remaining == 0) break;  // end of payload

  if (totalReadForChunk == chunkSize) {
     totalReadForChunk = 0;
     // read the chunk header (it's not neccessarily 0xc6)
     int header = read()
     if (header != currentStreamEmptyHeader) {  // 0xc6
       // ... parse the new rtmp message according to header value
       // (usually invoke the upper-level message reading method "recursively")
     }
  }
}

关于java - InputStream 读取源中不存在的额外字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36207933/

相关文章:

java - 为自定义组合框创建监听器逻辑

java - jni 从 jobject 访问 jobjectArray

python - HTTP 代理服务器 python [客户端帮助]

c++ - 如何从 wfstream 读取二进制数据?

java - 如何找到线程在 Java 中运行的 Quartz 作业?

python - 如何连接 2 个节点并使用 python 套接字通过它们发送数据?

java - 文件传输后保留文件名

c# - Stream.Seek(0, SeekOrigin.Begin) 或 Position = 0

java - 适用于 Android 蓝牙流式传输的缓冲阅读器

java - junit:开发测试用例的最佳实践?