【问题标题】:JAVA - Tftp client how to set block sizeJAVA - Tftp 客户端如何设置块大小
【发布时间】:2013-03-25 12:19:29
【问题描述】:

我正在编写一个 tftp 客户端,只要我使用默认块大小 (512),它就可以正常工作。但由于是学校作业,我还需要使用 1430 和 4300 的块大小对其进行测试。

当我第一次与服务器通信时,我使用这种方法:

public void setFilename( String s, String mode) {
        byte []a = s.getBytes();
        int i,j,k;
        for ( i=0; i+2<lenght && i<a.length; i++ ) {
            packet[i+2] = a[i];
        }
        packet[i+2] = 0;
        a = mode.getBytes();
        for ( j=0,i++; i<lenght && j<a.length; i++,j++ ) {
            packet[i+2] = a[j];
        }
        packet[i+2] = 0;


    }

它将设置我要读取的文件名。而且效果很好。

但是我已经改变了它,所以我可以定义一个块大小:

public void setFilename( String s, String mode, String blockSize ) {
        byte []a = s.getBytes();
        int i,j,k;
        for ( i=0; i+2<lenght && i<a.length; i++ ) {
            packet[i+2] = a[i];
        }
        packet[i+2] = 0;
        a = mode.getBytes();
        for ( j=0,i++; i<lenght && j<a.length; i++,j++ ) {
            packet[i+2] = a[j];
        }
        packet[i+2] = 0;

        a = BLOCKSIZE.getBytes();
        for ( k=0,i++; i<lenght && k<a.length; i++,k++ ) {
            packet[i+2] = a[k];
        }
        packet[i+2] = 0;

        a = blockSize.getBytes();
        for ( k=0,i++; i<lenght && k<a.length; i++,k++ ) {
            packet[i+2] = a[k];
        }
        packet[i+2] = 0;

    }

这里 BLOCKSIZE = "blksize" (string) and blockSize = 1430 (int); 问题是,它不起作用:-/

谁能给我解释一下如何定义块大小?

谢谢你们 :-)

【问题讨论】:

    标签: java networking tftp


    【解决方案1】:

    问题出在阅读部分,而不是在这里。 如果有人感兴趣,这是构建数据包的完整代码:-)

    /** *

    * TftpPacket - 将字节数组视为 tftp 数据包。 * *

    根据 TFTP 协议 (rfc 1350, 2347) 的消息格式。 *

    注意:这个实现假设所有使用的 JAva 字符串只包含 * ASCII 字符。如果不是这样,lenght() 和 getBytes() 返回不同的值 * 可能会出现意想不到的问题...

    *tftp 请求包 * 2 字节字符串 1 字节字符串 1 字节可选选项(字符串) * -----------------------------------------+ - - - + - + - - - + - + -> *RRQ/WRQ | 01/02 |文件名 | 0 |模式 | 0 |选择1 | 0 |值1| 0 | ... * -----------------------------------------+ - - - + - + - - - + - + -> * 模式(ascii 字符/每个 1 字节): * "netascii", "八位字节",... * * 2 字节 2 字节 n 字节 * --------------------------------- *数据 | 03 |块# |数据 | * --------------------------------- * 2 字节 2 字节 * ------------------- *确认 | 04 |块# | * -------- * 2 字节 2 字节 字符串 1 字节 * -------------------------- *错误 | 05 |错误代码 |错误消息 | 0 | * -------------------------- * 错误代码: * 0 未定义,请参阅错误消息(如果有)。 * 1 文件未找到。 * 2 访问冲突。 * 3 磁盘已满或超出分配。 * 4 非法 TFTP 操作。 * 5 未知的传输 ID。 * 6 文件已经存在。 * 7 没有这样的用户。 *

    */
    public class TftpPacket {
    
    // Opcodes
    protected static final short RRQ=1;
    protected static final short WRQ=2;
    protected static final short DATA=3;
    protected static final short ACK=4;
    protected static final short ERROR=5;
    protected static final String BLOCKSIZE = "blksize";
    
    byte []packet;
    int lenght;
    
    /**
     *  Builds a view to a byte array as a tftp packet.
     *  The original byte array is the one manipulated by all methods
     */
    public TftpPacket( byte []data, int len ) {
        packet = data;
        lenght = len;
    }
    
    /**
     *  Gets number at first two bytes of packet
     */
    public int getOpcode() {
        return (packet[0]<<8)|(packet[1]&0xff);  //net byte order = Big-Endian
    }
    
    /**
     *  Sets first two bytes of packet
     */
    public void setOpcode(int code) {
        packet[0] = (byte) ((code>>8)&0xff);
        packet[1] = (byte) (code&0xff);
    }
    
    /**
     *  Gets string starting at byte 2
     */
    public String getFileName() {
        int i;
        for ( i=2; i<lenght; i++ )
            if (packet[i]==0) //end of string
                return new String(packet, 2, i-2);
        return null;
    }
    
    /**
     *  Sets two strings (NUL terminated) starting at byte 2
     */
    public void setFilename( String s, String mode, String blockSize ) {
        byte []a = s.getBytes();
        int i,j,k;
        for ( i=0; i+2<lenght && i<a.length; i++ ) {
            packet[i+2] = a[i];
        }
        packet[i+2] = 0;
        a = mode.getBytes();
        for ( j=0,i++; i<lenght && j<a.length; i++,j++ ) {
            packet[i+2] = a[j];
        }
        packet[i+2] = 0;
    
        a = BLOCKSIZE.getBytes();
        for ( k=0,i++; i<lenght && k<a.length; i++,k++ ) {
            packet[i+2] = a[k];
        }
        packet[i+2] = 0;
    
        a = blockSize.getBytes();
        for ( k=0,i++; i<lenght && k<a.length; i++,k++ ) {
            packet[i+2] = a[k];
        }
        packet[i+2] = 0;
    
    }
    
    /**
     *  Gets second string in packet
     */
    public String getMode(){
        for ( int i=2; i<lenght; i++ )
            if (packet[i]==0) { //end of 1st string
                for ( int j=i+2; j<lenght; j++ )
                    if ( packet[j]==0 ) return new String(packet, i+1, j-i-1);
            }
        return null; 
    }
    
    /**
     *  Gets number at bytes 2 and 3 of packet (can be block count or error code)
     */
    public int getBlockCount() {
        return (packet[2]<<8)|(packet[3]&0xff);  //net byte order = Big-Endian
    }
    
    /**
     *  Sets bytes 2 and 3 of packet (can be block count or error code)
     */
    public void setBlockCount(int count) {
        packet[2] = (byte) ((count>>8)&0xff);
        packet[3] = (byte) (count&0xff);
    }
    
    /**
     *  Sets string (NUL-terminated) starting at byte 4
     */
    public void setErrMsg( String s ) {
        byte []a = s.getBytes();
        int i;
        for ( i=0; i<a.length; i++ ) {
            packet[i+4] = a[i];
        }
        packet[i+4] = 0;
    }
    

    }

    【讨论】:

      【解决方案2】:

      我建议您使用 Wireshark 并查看数据包如何被整合并发送到网络。 这样,您可以在代码中组装 TFTP 协议时非常快速地发现任何问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多