【问题标题】:How to get the file name from an RRQ datagramPacket?如何从 RRQ 数据报包中获取文件名?
【发布时间】:2016-03-11 12:26:41
【问题描述】:

我正在使用 TFTP 服务器。根据图片,我的数据包的最大长度为 516 字节 (2+2+512)。

我试图从客户端数据报包中获取原始长度(在这种情况下,在 RRQ 数据包中发送 13 个字节),而不是获取我保存客户端数据报包的服务器数据报包长度(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

【问题讨论】:

  • 你怎么知道客户端实际上只发送了 13 个字节?你用的是什么客户端?
  • 好的,抱歉,这是我的第一篇文章,正在处理中。
  • TFTP 说“文件名以空值结尾”。也许你应该依靠它。
  • “文件名以空值结尾”因为数据包长度,所以我依赖它。
  • 不,文件名以单个 0x00 结尾,然后是“模式”和另一个 0x00。该规范没有说明“数据包中的最后七个字节”。 (模式也可以是“netascii”...)

标签: java sockets server datagram tftp


【解决方案1】:

试试这个:

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

【讨论】:

  • 它说:线程“main”中的异常java.lang.NullPointerException:空地址||空缓冲区
  • 我尝试了类似在 inData 中搜索 byte(0+mode+0) 赞助人的索引(使用 Arrays.binarySearch()),也许有办法,但我没有到达原始长度。
  • 我想过写一个 if() 与空字节进行比较并在它找到的第一个空字节处返回字符串,但我没有找到与空字节的比较。
【解决方案2】:

我们可以通过在客户端类的文件名字符串中添加“\n”来实现,而不是获取接收数据包的原始长度(通过数组搜索文件名),然后使用 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-08
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    相关资源
    最近更新 更多