IndexOutOfBounds – ajuda necessária
-
13-12-2019 - |
Pergunta
O código abaixo foi projetado para receber um byte[] e várias outras coisas (veja o código que ele fornece).Em seguida, ele cria um pacote com um determinado comprimento e o retorna.Meu problema é que quando leio um arquivo para o programa principal, preciso que o buffer do pacote de datagrama seja o número de bytes restantes para serem enviados (se for menor que 512) + 4.Isto serve para lidar com o último pacote de uma solicitação de leitura de um servidor TFTP.Estou recebendo uma exceção de índice fora dos limites na linha "buffer[bufferOffset] = data[dataOffset];".Alguém pode me ajudar a entender por que isso está acontecendo e qual seria a melhor maneira de contornar isso?
public DatagramPacket doRRQ(byte[] data, int block, InetAddress address, int port, long fileSize, long sentBytes){
//takes file data and creates a buffer for a DATA packet to be used in a RRQ. This packet
//is passed to MyFirstTFTPServer.java to be modified and sent to client. This is done
int bufferOffset = 3;
int dataOffset = -1;
byte[] buffer = null;
long difference = 0;
int i = 512;
byte byteBlock = (byte)block++;//possible issue with block no increment. test.
if (sentBytes + 512 > fileSize){
difference = fileSize - sentBytes;
difference = difference + 4;
i = (int)difference;
buffer = new byte[i];
} else {
buffer = new byte[516];
}
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
buffer[0] = 0;
buffer[1] = 3;
buffer[2] = 0;
buffer[3] = byteBlock;
for(byte item:data){
bufferOffset++;
dataOffset++;
buffer[bufferOffset] = data[dataOffset];
//System.out.println(bufferOffset);
//System.out.println(dataOffset);
}
return packet;
}
Solução
Eu não vejo onde você já deu uma olhada data.length.
É possível que data.length seja maior que sentBytes?Nesse caso, seu loop deve ser sobre sendBytes, não sobre dados.
Basicamente, sua lógica para decidir o comprimento do buffer parece suspeitamente divorciada do tamanho de sentBytes.
Outras dicas
Este é o seu código refatorado para um formato compacto:
public DatagramPacket doRRQ(byte[] data, int block, InetAddress address,
int port, long fileSize, long sentBytes)
{
final byte[] buffer =
new byte[sentBytes + 512 > fileSize? (int)(fileSize - sentBytes) + 4 : 516];
final DatagramPacket packet =
new DatagramPacket(buffer, buffer.length, address, port);
buffer[1] = 3;
buffer[3] = (byte)block;
for (int i = 0; i < data.length; i++) buffer[i+3] = data[i];
return packet;
}
Agora é bastante óbvio o que está acontecendo.Sua expressão para o tamanho do buffer não depende diretamente de data.length
, então o problema pode estar nos valores do argumentos ao método, assim como pode estar no próprio código.Você é o juíz.