⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpclientagent.java

📁 用JAVA实现的TFTP原代码不错的东西
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * tftpClientAgent.java
 *
 * Created on 2007年4月29日, 上午9:31
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package tftpd;

import java.net.*;
import java.io.*;

/**
 *
 * @author Administrator
 */
public class tftpClientAgent extends Thread {
    
    /** Creates a new instance of tftpClientAgent */

    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();
        
    }
    
    public void RRQ() {
        int ntimeout = this.m_MAX_nTimeOut;
        try {
            short nblock = 1;
            //send the #0 block ACK to start the transfer
            if (!this.SendFile(nblock, this.m_filename, this.m_mode)) {
                this.SendERROR((short)0, "无法读取文件");
                return ;
            }
            
            //wait for the ACK packet
            while (ntimeout > 0) {
                DatagramPacket dp;
                dp = this.waitForData();
                
                if (dp == null) {
                    //this.SendERROR((short)0, "超时了,连接被服务器断开 ...");
                    //System.out.println("debug: tftpClientagent.RRQ() --> timeout: " + ntimeout);
                    ntimeout--;
                } else {
                    //ok, get a packet, check the ip and port
                    if (!((dp.getAddress().equals(this.m_ClientAddress))
                            && (dp.getPort() == this.m_ClientPort))) {
                        //ip or port has a mistake
                        //this.SendERROR((short)0, "我不认识你");
                        //System.out.println("debug: RRQ() --> ip or port error ...");
                        ntimeout--;
                    } else {    //right ip and port
                        //get the opcode
                        DataInputStream din = new DataInputStream(new ByteArrayInputStream(dp.getData()));
                        int opcode = din.readShort();
                        //System.out.println("debug: the opcode is " + opcode);
                        if (opcode != 4) {
                            //不是04号ACK包
                            if (opcode == 1 && nblock == 1) {
                                //是01号RRQ包,且正在等待#1号ACK包
                                //此时收到RRQ,说明#1号data有可能失败了,重发
                                if (!this.SendFile(nblock, this.m_filename, this.m_mode)) {
                                    this.SendERROR((short)0, "无法读取文件");
                                    return ;
                                }
                            } else {
                                this.SendERROR((short)4, "非法的TFTP操作");
                            }
                            
                            ntimeout--;
                        } else {    //is an ACK packet
                            //System.out.println("debug: get a ACK packet");
                            int nblk = din.readShort();
                            //System.out.println("debug: the waiting for #" + nblock + " -- the curBlock is #" + nblk);
                            if (nblk != nblock) {
                                //System.out.println("debug: re-SendFile(" + nblock + ")");
                                //不是期待的块号,重发data包,超时计数减1
                                if (!this.SendFile(nblock, this.m_filename, this.m_mode)) {
                                    this.SendERROR((short)0, "无法读取文件");
                                    return ;
                                }
                                ntimeout--;
                            } else {    //get the right ACK packet
                                //the rest of the special file
                                long restSize = this.getRestOfFile(nblock, this.m_filename);
                                //System.out.println("debug: the restSize = " + restSize);
                                if (restSize < 0) {
                                    //ok, 上次已经把剩余的发送完毕了,结束
                                    ntimeout = 0;
                                } else {
                                    //send the next block data
                                    nblock++;
                                    //System.out.println("debug: start sending ...");
                                    if (!this.SendFile(nblock, this.m_filename, this.m_mode)) {
                                        //System.out.println("debug: ERROR while sending the #" + nblock);
                                        this.SendERROR((short)0, "无法读取文件");
                                        ntimeout = 0;
                                    } else {
                                        //send succ
                                        //System.out.println("debug: send the #" + nblock);
                                        ntimeout = this.m_MAX_nTimeOut; //重置超时记数
                                        //continue wait for ACK of the current block
                                    }
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            //System.out.println("Exception in tftpClientAgent.RRQ() --> " + e.getMessage());
        }
    }
    
    public void WRQ() {
        int ntimeout = this.m_MAX_nTimeOut;
        try {
            short nblock = 0;
            //send the #0 block ACK to start the transfer
            this.SendACK(nblock++);
            
            //wait for the data packet
            while (ntimeout > 0) {
                DatagramPacket dp;
                dp = this.waitForData();
                //dp = new DatagramPacket(buf, 516);
                if (dp == null) {
                    //this.SendERROR((short)0, "超时了,连接被服务器断开 ...");
                    //System.out.println("debug: tftpClientagent.WRQ() --> timeout: " + ntimeout);
                    ntimeout--;
                } else {
                    //ok, get a packet, check the ip and port
                    if (!((dp.getAddress().equals(this.m_ClientAddress))
                            && (dp.getPort() == this.m_ClientPort))) {
                        //ip or port has a mistake
                        //this.SendERROR((short)0, "我不认识你");
                        //System.out.println("debug: ip or port error ...");
                        ntimeout--;
                    } else {    //right ip and port
                        //get the opcode
                        DataInputStream din = new DataInputStream(new ByteArrayInputStream(dp.getData()));
                        int opcode = din.readShort();
                        //System.out.println("debug: the opcode is " + opcode);
                        if (opcode != 3) {
                            //不是03号data包
                            if (opcode == 2 && nblock == 1) {
                                //是02号WRQ包,且正在等待#1号data包
                                //此时收到WRQ,说明#0号ACK有可能失败了,重发
                                this.SendACK((short)(nblock-1));
                            } else {
                                this.SendERROR((short)4, "非法的TFTP操作");
                            }
                            
                            ntimeout--;
                        } else {    //data packet
                            //System.out.println("debug: get a data packet");
                            int nblk = din.readShort();
                            //System.out.println("debug: the waiting for #" + nblock + " -- the curBlock is #" + nblk);
                            if (nblk != nblock) {
                                //System.out.println("debug: re-SendACK(" + (nblock-1) + ")");
                                //不是期待的块号,重发上一个包的ACK,超时计数减1
                                this.SendACK((short)(nblock-1));
                                ntimeout--;
                            } else {    //the right packet waiting for
                                //this.SaveFile(this.m_filename);
                                if (!this.SaveFile(nblock, dp, this.m_filename, this.m_mode)) {
                                    ntimeout = 0;
                                    this.SendERROR((short)3, "磁盘满或超过分配的配额");
                                } else {
                                    //send the current block ACK
                                    this.SendACK(nblock);
                                    //System.out.println("debug: dp.length = " + (dp.getLength()-4));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -