问题出在阅读部分而不是在这里。如果有人感兴趣,这是构建数据包的完整代码:-)
/** *
* 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;
}
}