Как получить имя файла из пакета RRQ datagramPacket?

Я работаю на TFTP-сервере. Судя по изображению, максимальная длина моих пакетов составляет 516 байт (2+2+512).

Я пытаюсь взять исходную длину из пакета клиентских дейтаграмм (в данном случае отправляет 13 байтов в пакете RRQ), вместо этого я получаю длину пакета дейтаграмм сервера (516 байт), где я сохраняю пакет дейтаграмм клиента.

Мне нужно это для извлечения имени файла, я сделал это, но содержимое строки «имя файла + nullBytes», эти нулевые байты поступают из пакета датаграммы сервера.

Это код, в котором я застрял:

public static short RRQ = 1;
        enter code here
    public void dataMetod() throws IOException{
                        byte[] packet = new byte[516];
                        //socket with listening port 5000
                        DatagramSocket datagramSocket = new DatagramSocket(5000);

                    //while receive packets
                    while (true) {
                    DatagramPacket datagramPacket = new  DatagramPacket(packet,packet.length);
                    datagramSocket.receive(datagramPacket);
                    System.out.println("server: new packet!!:");

                    //create a byte[] with the "received packet length"(that's not true)
                    byte[] inData = new byte[datagramPacket.getLength()];
                    inData = datagramPacket.getData();

                    System.out.println("length: "+inData.length);
                    byte code;
                    code = inData[1];
                    System.out.println(code);

                    //check if its an RRQ packet
                    if (code == RRQ) {
                        System.out.println("server: RRQ PACKET!!");
                        String fileName = this.getFileName(inData);
                        System.out.println(fileName);


                }

public String getFileName(byte[] inData) {
        byte[] aux = new byte[inData.length - 7];
        for (int i = 0; i < aux.length; i++) {
            aux[i] = inData[i + 2];
        }
        return new String(aux);
    }

http://i.stack.imgur.com/6dTH6.png


person Community    schedule 11.03.2016    source источник
comment
Откуда вы знаете, что клиент на самом деле отправил только 13 байт? Какой клиент вы используете?   -  person JimmyB    schedule 11.03.2016
comment
ОК, извините, это мой первый пост, работаю над ним.   -  person    schedule 11.03.2016
comment
TFTP говорит, что имя файла завершается нулем. Может быть, вам стоит полагаться именно на это.   -  person JimmyB    schedule 11.03.2016
comment
имя файла завершается нулем из-за длины пакета, поэтому я полагаюсь на это.   -  person    schedule 11.03.2016
comment
Нет, имя файла заканчивается одним 0x00, затем идет режим и еще 0x00. Спецификация ничего не говорит о последних семи байтах в пакете. (режим также может быть netascii...)   -  person JimmyB    schedule 11.03.2016


Ответы (2)


Попробуй это:

public String getFileName(byte[] inData) {

    final int maxLen = inData.length;

    final StringBuilder sb = new StringBuilder();

    int i = 2;
    byte b;

    while ( (i < maxLen) && (b = inData[i]) != 0 ) {
        final int v = ((int)b) & 0xff;
        sb.append( (char) v );
        i++;
    }
    return sb.toString();
}
person JimmyB    schedule 11.03.2016
comment
В нем говорится: Исключение в потоке main java.lang.NullPointerException: нулевой адрес || нулевой буфер - person ; 12.03.2016
comment
Я пробовал что-то вроде поиска по индексу патрона byte(0+mode+0) в inData (с помощью Arrays.binarySearch()), возможно, есть способ с этим, но я не пришел, чтобы получить исходную длину. - person ; 12.03.2016
comment
Я думал написать if(), который сравнивает с нулевыми байтами и возвращает строку в 1-м найденном нулевом байте, но я не нашел сравнения с нулевыми байтами. - person ; 13.03.2016

Вместо получения исходной длины полученного пакета (для поиска имени файла в массиве) мы могли бы сделать это, добавив «\n» в строку fileName в клиентском классе, а затем использовать BufferedReader, который обнаружит «\n» и сохранит имя файла. Код:

    public String getFileName(byte[] inData) throws IOException {

    //get a sub-array, from index[2] (beacuse we dont want opCode) to inData length

        byte[] b =Arrays.copyOfRange(inData, 2, inData.length);

        InputStream is = new ByteArrayInputStream(b);
        BufferedReader bf = new BufferedReader(new InputStreamReader(is));

    //We read a word that will be saved when "\n" is found.
    //(adding "\n" previously to the fileName String in client class)

        String filename = bf.readLine();
        bf.close();
        is.close();
        System.out.println("server: filename is: "+filename.length()+" bytes");
        return filename;
}
person Community    schedule 14.03.2016