J'ai essayé d'écrire un serveur HTTP java à partir de zéro pour mon programme de chat qui envoie des données sur les Websockets et tout s'est bien passé jusqu'à ce que je tente d'envoyer de grandes images avec mon programme en utilisant google chrome. J'ai découvert que lorsque Chrome envoie plusieurs images de données à mon serveur, il n'envoie jamais la bonne longueur de données. La première image est toujours correcte, mais toutes les images après l'initiale envoient un nombre significativement plus petit que les données contenues dans l'image. Par exemple, il enverra une trame indiquant qu'il contient 123 octets de données, alors qu'il envoie en réalité plus de 100 kilo-octets. J'ai testé d'autres navigateurs comme Firefox et Safari (sur mon téléphone) et ils ne semblent pas diviser de grandes données dans des cadres comme le fait le chrome, donc ils n'ont pas le même problème. Voici quelques captures d'écran de mes résultats: cadre initial: enter image description hereProblèmes avec l'envoi de données volumineuses sur Websockets avec Chrome
cadres suivants (C'est là où il échoue): enter image description here
Et voici mon code côté serveur qui récupère les données à partir d'un flux d'entrée et écrit dans un fichier:
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;
Toute explication à laquelle je pourrais manquerais de lire la longueur des cadres suivants seraient grandement appréciés (j'ai quelques soupçons de ma propre aussi bien). Merci pour votre temps et vos efforts.
Vous continuez à supposer que 'read()' remplit le tampon, sans vérifier la fin du flux ou une lecture courte. Utilisez 'DataInputStream.readFully()': en fait certaines de ces lectures pourraient être faites avec 'readInt()' et des amis. – EJP