2

我正在编写一个 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) 和 blockSize = 1430 (int); 问题是,它不起作用:-/

有人可以向我解释如何定义块大小吗?

感谢你们 :-)

4

2 回答 2

0

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

/** *

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

}

于 2014-04-15T09:59:09.837 回答
-3

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

于 2013-03-25T14:43:21.610 回答