私は自分のプログラムで大きな画像を送信しようとするまで、Webソケットを介してデータを送信するチャットプログラムのために、最初からJava HTTPサーバーを作成しようとしています。 Google Chromeを使用して私は、クロムが複数のフレームのデータをサーバーに送信しているときに、データの適切な長さを送信しないことを発見しました。最初のフレームは常に問題ありませんが、最初のフレーム以降のすべてのフレームは、フレームに含まれるデータよりもかなり小さい番号を送信します。たとえば、実際に100キロバイトを超えるデータを送信しているときに123バイトのデータが含まれているというフレームを送信します。私はfirefoxやsafari(私の電話で)のような他のブラウザをテストしましたが、クロムのように大きなデータをフレームに分割しないように見えるので、同じ問題はありません。ここに私の結果のいくつかのスクリーンショットは、以下のとおりです。 初期フレーム: enter image description hereChromeで大量のデータを送信する際の問題
フレームに続いて(それが失敗した場所です): 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()'とお友達で行うことができます。 – EJP