下面的代码旨在获取一个 byte[] 和其他一些东西(请参阅它给出的代码)。然后它构建一个具有一定长度的数据包并返回该数据包。我的问题是,当我将文件读入主程序时,我需要数据报包的缓冲区为剩余发送的字节数(如果小于 512)+ 4。这是为了处理 TFTP 服务器读取请求的最后一个数据包。我在“buffer[bufferOffset] = data[dataOffset];”行上遇到索引越界异常。谁能帮助我理解为什么会发生这种情况以及最好的解决方法是什么?

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;

}
有帮助吗?

解决方案

我没有看到你曾经看过的那样,它可以看到data.length比entybytes大吗?如果是这样,你的循环应该超过SentBytes,而不是通过数据。

基本上,要决定缓冲区缓冲区长度的逻辑似乎可疑地离婚了截至截至的大小。

其他提示

这是您的代码重构为紧凑的形式:

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;
}

现在发生的事情已经很明显了。您的缓冲区大小表达式并不直接取决于 data.length, ,所以问题可能出在 论点 到方法中,就像它可以位于代码本身中一样。你来当法官吧。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top