【发布时间】:2018-05-16 05:08:29
【问题描述】:
我一直在尝试为我的聊天程序从头开始编写一个 java HTTP 服务器,该服务器通过 websockets 发送数据,并且一切都进展顺利,直到我开始尝试使用我的程序使用 google chrome 发送大图像。我发现当 chrome 向我的服务器发送多帧数据时,它永远不会发送正确长度的数据。第一帧总是好的,但是在初始帧之后的所有帧都发送一个比帧包含的数据小得多的数字。例如,它会发送一个帧,说它包含 123 个字节的数据,而实际上它发送的数据超过 100 KB。我已经测试了其他浏览器,如 firefox 和 safari(在我的手机上),它们似乎没有像 chrome 那样将大数据分成帧,所以它们没有同样的问题。以下是我的结果的一些截图: 初始帧: enter image description here
以下帧(这是失败的地方): enter image description here
这是我的服务器端代码,它从输入流中获取数据并将其写入文件:
byte[] headerdata = new byte[12];
input.read(headerdata, 0, 2);
int frame = (headerdata[0] & 0b10000000) & 0xFF;
long length = (headerdata[1] & 0b01111111) & 0xFF;
System.out.format("Before: %d, Frame: %d%n", length, frame);
if(length == 127){
input.read(headerdata, 0, 12);
length = ((long)(headerdata[0] << 56) & 0xFFFFFFFFFFFFFFFFL | (long)(headerdata[1] << 48) & 0xFFFFFFFFFFFFFFL | (long)(headerdata[2] << 40) & 0xFFFFFFFFFFFFL | (long)(headerdata[3] << 32) & 0xFFFFFFFFFFL | (headerdata[4] << 24) & 0xFFFFFFFFL | (headerdata[5] << 16) & 0xFFFFFFL | (headerdata[6] << 8) & 0xFFFFL | headerdata[7] & 0xFFL)
} else if(length == 126){
input.read(headerdata, 6, 6);
length = ((headerdata[6] << 8) & 0xFFFF | headerdata[7] & 0xFF);
}else{
input.read(headerdata, 8, 4);
}
System.out.println("After: " + length);
int count;
int total = 0;
byte[] buffer = new byte[16384];
boolean done = false;
while(done == false){
count = input.read(buffer, 0, buffer.length);
//System.out.println(count);
for(int i = 0; i < count; i++){
buffer[i] = (byte)(buffer[i] ^ headerdata[(total & 3) + 8]);
total++;
}
fileoutput.write(buffer, 0, count);
System.out.format("Count: %d Left: %d%n", count, (length - total));
if(total >= length){
done = true;
}
}
if(frame == 128) break;
任何关于我为什么可能无法阅读后续帧长度的解释将不胜感激(我自己也有一些怀疑)。感谢您的时间和努力。
【问题讨论】:
-
你一直假设
read()填充了缓冲区,而不检查流的结尾或短读。使用DataInputStream.readFully():实际上其中一些读取可以使用readInt()和朋友来完成。
标签: java google-chrome websocket