Package org.jnode.net.ipv4.tftp

Source Code of org.jnode.net.ipv4.tftp.TFTPServer

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.net.ipv4.tftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import org.apache.commons.net.tftp.TFTP;
import org.apache.commons.net.tftp.TFTPAckPacket;
import org.apache.commons.net.tftp.TFTPDataPacket;
import org.apache.commons.net.tftp.TFTPErrorPacket;
import org.apache.commons.net.tftp.TFTPPacket;
import org.apache.commons.net.tftp.TFTPPacketException;
import org.apache.commons.net.tftp.TFTPReadRequestPacket;
import org.apache.commons.net.tftp.TFTPWriteRequestPacket;
import org.apache.log4j.Logger;

/**
* TFTP server. Currently only supports one client at a time.
*
* @author markhale
*/
public class TFTPServer extends TFTP {

    private static final Logger log = Logger.getLogger(TFTPServer.class);

    /** current client address */
    private InetAddress clientAddress;
   
    private int clientPort;
    /** send transfer stream */
   
    private FileInputStream fileIn;
    /** receive transfer stream */
   
    private FileOutputStream fileOut;
    /** current block number received or sent */
   
    private int blockNumber;

    public static void main(String[] args) {
        TFTPServer server = new TFTPServer();
        try {
            server.run();
        } catch (SocketException ex) {
            Logger.getLogger(TFTPServer.class).fatal("Socket exception", ex);
        }
    }

    private void run() throws SocketException {
        System.out.println("JNode TFTP Server");
        open(DEFAULT_PORT);
        setSoTimeout(0);
        beginBufferedOps();
        try {
            boolean doShutdown = false;
            while (!doShutdown) {
                try {
                    TFTPPacket packet = bufferedReceive();
                    processRequest(packet);
                } catch (TFTPPacketException ex) {
                    log.debug("Error in TFTP packet", ex);
                } catch (IOException ex) {
                    log.debug("I/O exception", ex);
                }
            }
        } finally {
            endBufferedOps();
            close();
        }
    }

    private void processRequest(TFTPPacket packet) throws IOException {
        if (log.isDebugEnabled())
            log.debug("Received packet: " + packet.getAddress() + ':' + packet.getPort());
        final int type = packet.getType();
        switch (type) {
            case TFTPPacket.WRITE_REQUEST:
                if (clientAddress == null) {
                    TFTPWriteRequestPacket wreqPacket = (TFTPWriteRequestPacket) packet;
                    File file = new File(".", wreqPacket.getFilename());
                    log.info("Request to write file " + wreqPacket.getFilename() + " (" +
                            file.getAbsolutePath() + ") received from " + packet.getAddress() +
                        ':' + packet.getPort());
                    fileOut = new FileOutputStream(file);
                    blockNumber = 0;
                    bufferedSend(new TFTPAckPacket(packet.getAddress(), packet.getPort(), blockNumber));
                    clientAddress = packet.getAddress();
                    clientPort = packet.getPort();
                }
                break;
            case TFTPPacket.DATA:
                if (packet.getAddress().equals(clientAddress) && packet.getPort() == clientPort) {
                    TFTPDataPacket dataPacket = (TFTPDataPacket) packet;
                    // if client sent next block
                    if (dataPacket.getBlockNumber() == blockNumber + 1) {
                        fileOut.write(dataPacket.getData(), dataPacket.getDataOffset(), dataPacket
                                .getDataLength());
                        // send acknowledgement
                        bufferedSend(new TFTPAckPacket(packet.getAddress(), packet.getPort(),
                                dataPacket.getBlockNumber()));
                        blockNumber++;
                        // if last block then end of transfer
                        if (dataPacket.getDataLength() < TFTPDataPacket.MAX_DATA_LENGTH) {
                            clientAddress = null;
                            clientPort = 0;
                            fileOut.close();
                        }
                    }
                }
                break;
            case TFTPPacket.READ_REQUEST:
                if (clientAddress == null) {
                    TFTPReadRequestPacket rreqPacket = (TFTPReadRequestPacket) packet;
                    try {
                        File file = new File(".", rreqPacket.getFilename());
                        log.info("Request to read file " + rreqPacket.getFilename() + " (" +
                                file.getAbsolutePath() + ") received from " + packet.getAddress() +
                            ':' + packet.getPort());
                        fileIn = new FileInputStream(file);
                        blockNumber = 1;
                        byte[] data = new byte[TFTPDataPacket.MAX_DATA_LENGTH];
                        final int bytesRead = fileIn.read(data);
                        bufferedSend(new TFTPDataPacket(packet.getAddress(), packet.getPort(),
                                blockNumber, data, 0, bytesRead));
                        // if more blocks to send
                        if (bytesRead == TFTPDataPacket.MAX_DATA_LENGTH) {
                            clientAddress = packet.getAddress();
                            clientPort = packet.getPort();
                        } else {
                            fileIn.close();
                        }
                    } catch (FileNotFoundException ex) {
                        bufferedSend(new TFTPErrorPacket(packet.getAddress(), packet.getPort(),
                                TFTPErrorPacket.FILE_NOT_FOUND, ex.getMessage()));
                    }
                }
                break;
            case TFTPPacket.ACKNOWLEDGEMENT:
                if (packet.getAddress().equals(clientAddress) && packet.getPort() == clientPort) {
                    TFTPAckPacket ackPacket = (TFTPAckPacket) packet;
                    // if client acknowledged last block
                    if (ackPacket.getBlockNumber() == blockNumber) {
                        // send next block
                        byte[] data = new byte[TFTPDataPacket.MAX_DATA_LENGTH];
                        final int bytesRead = fileIn.read(data);
                        blockNumber++;
                        bufferedSend(new TFTPDataPacket(packet.getAddress(), packet.getPort(),
                                blockNumber, data, 0, bytesRead));
                        // if last block then end of transfer
                        if (bytesRead < TFTPDataPacket.MAX_DATA_LENGTH) {
                            clientAddress = null;
                            clientPort = 0;
                            fileIn.close();
                        }
                    }
                }
                break;
        }
    }
}
TOP

Related Classes of org.jnode.net.ipv4.tftp.TFTPServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.