这几天看了一下tftp协议,非常简单,这个学期选修的JAVA,
想趁这个机会练习一下,写一个tftp server的,刚刚把demo完成了,
用windows2003的tftp客户端测试过了,也用我的ADSL (嵌入式linux)里面的tftp测试过,demo版本还是挺好的,至少可以用 。。。
=================================================
源代码可以在这里下载: UploadFiles/2007-5/53552715.zip
文章在博客中的地址: http://blog.bc-cn.net/user1/37/archives/2007/5202.shtml
=================================================
因为tftp协议本身就很简单,所以我的代码就用了三个类文件,
Main.java --> 这个是启动代码,这个demo版本中,
他只是建立一个ServerAgent的对象,然后启动这个对象
tftpServerAgent.java --> 这是Server,它一直监听UDP Port 69,
来了新的连接,它就创建一个ClientAgent,
自己继续等待。
tftpClientAgent.java --> 这是与ftp客户端通信的类,它处理RRQ和WRQ
请求。
这两个Agent都继承了Thread,因为我想在以后的版本中加入Server的管理功能。
============================================
主要代码:
=================================
Main.java
===========================================
/** Creates a new instance of Main */
public Main() {
}
public static void main(String[] args) throws Exception {
// TODO code application logic here
tftpServerAgent tftp_srv = new tftpServerAgent();
tftp_srv.setDaemon(true);
tftp_srv.start();
tftp_srv.join(); //暂时先这么处理吧
}
}
=======================================
tftpServerAgent.java
===========================================
public class tftpServerAgent extends Thread {
//over the parent's run methord
public void run() {
try {
DatagramSocket tftpd = new DatagramSocket(69); //tftp server socket
byte[] buf = new byte[516]; //a buffer for UDP packet
DatagramPacket dp = new DatagramPacket(buf, 516); //a UDP packet
DataInputStream din = null;
tftpClientAgent newClient = null;
short tftp_opcode = 0; //opcode: the 2 bytes in the front of tftp packet
String tftp_filename = null;
String tftp_mode = null;
while (true) {
tftpd.receive(dp); //wait for a client
buf = dp.getData(); //get the UDP packet data
din = new DataInputStream(new ByteArrayInputStream(buf));
tftp_opcode = din.readShort(); //get the opcode
{ //get the filename
int fnoffset = 2;
int fnlen = 0;
while (din.readByte() != 0) {
fnlen++; //filename will end with a null char('\0')
}
tftp_filename = new String(buf, fnoffset, fnlen);
//get the mode
int mdnoffset = fnoffset + fnlen + 2;
int mdnlen = 0;
while (din.readByte() != 0) {
mdnlen++; //filename will end with a null char('\0')
}
tftp_mode = new String(buf, mdnoffset, mdnlen);
}
switch (tftp_opcode) {
case 1:
//RRQ
case 2:
//WRQ
newClient = new tftpClientAgent(dp.getAddress(), dp.getPort(), tftp_opcode, tftp_filename, tftp_mode);
newClient.setDaemon(true);
newClient.start();
this.m_hashClients.put(dp.getAddress().toString()+dp.getPort(), newClient);
//System.out.println("debug: Main.main() --> a RRQ thread start ....");
break;
}
}
} catch (Exception e) {
}
}
}
=========================================
tftpClientAgent.java
=========================================
public tftpClientAgent(InetAddress ip, int port, short opcode, String fname, String mode) {
this.m_ClientAddress = ip;
this.m_ClientPort = port;
this.m_curopcode = opcode;
this.m_filename = fname;
this.m_mode = mode;
}
public void run() {
int nfail = 100;
while (nfail-- > 0) {
//try getFreePort 100 times
try {
this.m_so_tftp = new DatagramSocket(this.getFreePort());
break; //get a random port number
} catch (SocketException e) {
}
}
//ok, the UDP socket is ready, response to the client
switch (this.m_curopcode) {
case 1:
//RRQ
this.RRQ();
break;
case 2:
//WRQ
this.WRQ();
//System.out.println("debug: tftpClientAgent.run() --> a WRQ ended ...");
break;
}
this.m_so_tftp.close();
}
}
private InetAddress m_ClientAddress; //ip of the client
private int m_ClientPort; //port of the client
private DatagramSocket m_so_tftp; //the socket object send or get message
private short m_curopcode; //the current opcode( wrq/rrq )
private String m_filename;
private String m_mode;
private final int m_MAX_nTimeOut = 5
[此贴子已经被作者于2007-5-3 21:08:20编辑过]