ftpconnection.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 1,082 行 · 第 1/2 页

JAVA
1,082
字号
/* * $Id: FTPConnection.java,v 1.1 2004/01/10 23:34:31 dalibor Exp $ * Copyright (C) 2003 The Free Software Foundation *  * This file is part of GNU inetlib, a library. *  * GNU inetlib is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. *  * GNU inetlib 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 General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *  * As a special exception, if you link this library with other files to * produce an executable, this library does not by itself cause the * resulting executable to be covered by the GNU General Public License. * This exception does not however invalidate any other reasons why the * executable file might be covered by the GNU General Public License. */package gnu.inet.ftp;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.net.BindException;import java.net.InetAddress;import java.net.ProtocolException;import java.net.Socket;import java.net.UnknownHostException;import java.util.ArrayList;import java.util.List;import gnu.inet.util.CRLFInputStream;import gnu.inet.util.LineInputStream;/** * An FTP client connection, or PI. * This implements RFC 959, with the following exceptions: * <ul> * <li>STAT, HELP, SITE, SMNT, and ACCT commands are not supported.</li> * <li>the TYPE command does not allow alternatives to the default bytesize * (Non-print), and local bytesize is not supported.</li> * </ul> * * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a> * @version $Revision: 1.1 $ $Date: 2004/01/10 23:34:31 $ */public class FTPConnection{  /**   * The default FTP transmission control port.   */  public static final int FTP_PORT = 21;        /**	 * The FTP data port.	 */  public static final int FTP_DATA_PORT = 20;  // -- FTP vocabulary --  protected static final String USER = "USER";  protected static final String PASS = "PASS";  protected static final String ACCT = "ACCT";  protected static final String CWD = "CWD";  protected static final String CDUP = "CDUP";  protected static final String SMNT = "SMNT";  protected static final String REIN = "REIN";  protected static final String QUIT = "QUIT";  protected static final String PORT = "PORT";  protected static final String PASV = "PASV";  protected static final String TYPE = "TYPE";  protected static final String STRU = "STRU";  protected static final String MODE = "MODE";  protected static final String RETR = "RETR";  protected static final String STOR = "STOR";  protected static final String STOU = "STOU";  protected static final String APPE = "APPE";  protected static final String ALLO = "ALLO";  protected static final String REST = "REST";  protected static final String RNFR = "RNFR";  protected static final String RNTO = "RNTO";  protected static final String ABOR = "ABOR";  protected static final String DELE = "DELE";  protected static final String RMD = "RMD";  protected static final String MKD = "MKD";  protected static final String PWD = "PWD";  protected static final String LIST = "LIST";  protected static final String NLST = "NLST";  protected static final String SITE = "SITE";  protected static final String SYST = "SYST";  protected static final String STAT = "STAT";  protected static final String HELP = "HELP";  protected static final String NOOP = "NOOP";  public static final int TYPE_ASCII = 1;  public static final int TYPE_EBCDIC = 2;  public static final int TYPE_BINARY = 3;  public static final int STRUCTURE_FILE = 1;  public static final int STRUCTURE_RECORD = 2;  public static final int STRUCTURE_PAGE = 3;  public static final int MODE_STREAM = 1;  public static final int MODE_BLOCK = 2;  public static final int MODE_COMPRESSED = 3;  // -- Telnet constants --  private static final String US_ASCII = "US-ASCII";  private static final byte[] CRLF = { 0x0d, 0x0a };  /**	 * The socket used to communicate with the server.	 */  protected Socket socket;  /**	 * The socket input stream.	 */  protected LineInputStream in;  /**	 * The socket output stream.	 */  protected OutputStream out;  /**	 * If true, print debugging information.	 */  protected boolean debug;  /**	 * The current data transfer process in use by this connection.	 */  protected DTP dtp;  /**	 * The current representation type.	 */  protected int representationType = TYPE_ASCII;  /**	 * The current file structure type.	 */  protected int fileStructure = STRUCTURE_FILE;  /**	 * The current transfer mode.	 */  protected int transferMode = MODE_STREAM;  /**	 * If true, use passive mode.	 */  protected boolean passive = false;  /**   * Creates a new connection to the server using the default port.	 * @param hostname the hostname of the server to connect to   */  public FTPConnection(String hostname)    throws UnknownHostException, IOException  {    this(hostname, -1, -1, -1, false);  }  /**   * Creates a new connection to the server.	 * @param hostname the hostname of the server to connect to	 * @param port the port to connect to (if &lt;=0, use default port)   */  public FTPConnection(String hostname, int port)    throws UnknownHostException, IOException  {    this(hostname, port, -1, -1, false);  }  /**   * Creates a new connection to the server.	 * @param hostname the hostname of the server to connect to	 * @param port the port to connect to (if &lt;=0, use default port)	 * @param connectionTimeout the connection timeout, in milliseconds	 * @param timeout the I/O timeout, in milliseconds	 * @param debug print debugging information   */  public FTPConnection(String hostname, int port,                       int connectionTimeout, int timeout, boolean debug)    throws UnknownHostException, IOException  {    this.debug = debug;    if (port <= 0)      port = FTP_PORT;    // Set up socket    // TODO connection timeout    socket = new Socket(hostname, port);    if (timeout > 0)      socket.setSoTimeout(timeout);    InputStream in = socket.getInputStream();      in = new BufferedInputStream(in);      in = new CRLFInputStream(in);      this.in = new LineInputStream(in);    OutputStream out = socket.getOutputStream();      this.out = new BufferedOutputStream(out);    // Read greeting    FTPResponse response = getResponse();    switch (response.getCode())    {    case 220:                  // hello      break;      default:throw new FTPException(response);    }  }  /**	 * Authenticate using the specified username and password.	 * If the username suffices for the server, the password will not be used	 * and may be null.	 * @param username the username	 * @param password the optional password	 * @return true on success, false otherwise	 */  public boolean authenticate(String username, String password)    throws IOException  {    String cmd =      new StringBuffer(USER).append(' ').append(username).toString();      send(cmd);    FTPResponse response = getResponse();    switch (response.getCode())    {      case 230:                  // User logged in        return true;      case 331:                 // User name okay, need password        break;      case 332:                 // Need account for login      case 530:                 // No such user        return false;      default:throw new FTPException(response);    }    cmd = new StringBuffer(PASS).append(' ').append(password).toString();    send(cmd);    response = getResponse();    switch (response.getCode())    {      case 230:                  // User logged in      case 202:                  // Superfluous        return true;      case 332:                  // Need account for login      case 530:                  // Bad password        return false;      default:        throw new FTPException(response);    }  }  /**	 * Changes directory to the specified path.	 * @param path an absolute or relative pathname	 * @return true on success, false if the specified path does not exist	 */  public boolean changeWorkingDirectory(String path) throws IOException  {    String cmd = new StringBuffer(CWD).append(' ').append(path).toString();    send(cmd);    FTPResponse response = getResponse();    switch (response.getCode())    {      case 250:        return true;      case 550:return false;      default:throw new FTPException(response);    }  }  /**	 * Changes directory to the parent of the current working directory.	 * @return true on success, false otherwise	 */  public boolean changeToParentDirectory() throws IOException  {    send(CDUP);    FTPResponse response = getResponse();    switch (response.getCode())    {      case 250:        return true;      case 550:return false;      default:throw new FTPException(response);    }  }  /**	 * Terminates an authenticated login.	 * If file transfer is in progress, it remains active for result response	 * only.	 */  public void reinitialize() throws IOException  {    send(REIN);    FTPResponse response = getResponse();    switch (response.getCode())    {    case 220:      if (dtp != null)      {        dtp.complete();        dtp = null;      }      break;    default:      throw new FTPException(response);    }  }  /**	 * Terminates the control connection.	 * The file transfer connection remains open for result response only.	 * This connection is invalid and no further commands may be issued.	 */  public void logout() throws IOException  {    send(QUIT);    try    {      getResponse();            // not required    }    catch(IOException e)    {    }    if (dtp != null)    {      dtp.complete();      dtp = null;    }    try    {      socket.close();    }    catch(IOException e)    {    }  }  /**	 * Initialise the data transfer process.	 */  protected void initialiseDTP() throws IOException  {    if (dtp != null)    {      dtp.complete();      dtp = null;    }    InetAddress localhost = socket.getLocalAddress();    if (passive)    {      send(PASV);      FTPResponse response = getResponse();      switch (response.getCode())      {      case 227:        String message = response.getMessage();        try        {          int start = message.indexOf(',');          char c = message.charAt(start - 1);          while (c > 0x30 && c < 0x39)            c = message.charAt((--start) - 1);          int mid1 = start;          for (int i = 0; i < 4; i++)            mid1 = message.indexOf(',', mid1 + 1);          int mid2 = message.indexOf(',', mid1 + 1);          int end = mid2;          c = message.charAt(end + 1);          while (c > 0x30 && c < 0x39)            c = message.charAt((++end) + 1);          String address = message.substring(start, mid1).replace(',', '.');          int port_hi = Integer.parseInt(message.substring(mid1 + 1, mid2));          int port_lo =            Integer.parseInt(message.substring(mid2 + 1, end + 1));          int port = (port_hi << 8) | port_lo;          System.out.println("Entering passive mode: " + address + ":" +                             port);          dtp = new PassiveModeDTP(address, port, localhost);          break;        }        catch(ArrayIndexOutOfBoundsException e)        {          throw new ProtocolException(e.getMessage() + ": " + message);        }        catch(NumberFormatException e)        {          throw new ProtocolException(e.getMessage() + ": " + message);        }      default:        throw new FTPException(response);      }    }    else    {      // Get the local port      int port = socket.getLocalPort() + 1;      int tries = 0;      // Bind the active mode DTP      while (dtp == null)      {        try        {          dtp = new ActiveModeDTP(localhost, port);          System.out.println("Listening on: " + port);        }        catch(BindException e)        {          port++;          tries++;          if (tries > 9)            throw e;        }      }      // Send PORT command      StringBuffer buf = new StringBuffer(PORT);      buf.append(' ');      // Construct the address/port string form      byte[]address = localhost.getAddress();      for (int i = 0; i < address.length; i++)      {        int a = (int) address[i];        if (a < 0)          a += 0x100;        buf.append(a);        buf.append(',');      }      int port_hi = (port & 0xff00) >> 8;      int port_lo = (port & 0x00ff);      buf.append(port_hi);      buf.append(',');      buf.append(port_lo);      send(buf.toString());      // Get response      FTPResponse response = getResponse();      switch (response.getCode())      {      case 200:                // OK        break;      default:        dtp.abort();        dtp = null;        throw new FTPException(response);      }    }    dtp.setTransferMode(transferMode);  }  /**	 * Set passive mode.	 * @param flag true if we should use passive mode, false otherwise	 */  public void setPassive(boolean flag) throws IOException  {    if (passive != flag)    {      passive = flag;      initialiseDTP();    }  }  /**	 * Returns the current representation type of the transfer data.	 * @return TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY	 */  public int getRepresentationType()  {    return representationType;  }  /**   * Sets the desired representation type of the transfer data.	 * @param type TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY	 */  public void setRepresentationType(int type) throws IOException  {    StringBuffer buf = new StringBuffer(TYPE);      buf.append(' ');    switch (type)    {    case TYPE_ASCII:      buf.append('A');      break;      case TYPE_EBCDIC:buf.append('E');      break;      case TYPE_BINARY:buf.append('I');      break;      default:throw new IllegalArgumentException(Integer.toString(type));    }    //buf.append(' ');    //buf.append('N');    send(buf.toString());    FTPResponse response = getResponse();    switch (response.getCode())    {    case 200:      representationType = type;      break;    default:      throw new FTPException(response);    }  }  /**	 * Returns the current file structure type.	 * @return STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE	 */  public int getFileStructure()  {    return fileStructure;  }  /**	 * Sets the desired file structure type.	 * @param structure STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE	 */  public void setFileStructure(int structure) throws IOException

⌨️ 快捷键说明

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