📄 ftpconnection.java
字号:
/* @(#) FTPConnection.java * <p>Copyright: Copyright (c) 2003,2004 Rad Inks</p> * <p>Company: Rad Inks (Pvt) Ltd.</p> *//* * License * * The contents of this file are subject to the Jabber Open Source License * Version 1.0 (the "JOSL"). You may not copy or use this file, in either * source code or executable form, except in compliance with the JOSL. You * may obtain a copy of the JOSL at http://www.jabber.org/ or at * http://www.opensource.org/. * * Software distributed under the JOSL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the JOSL * for the specific language governing rights and limitations under the * JOSL. */package com.radinks.net;import javax.swing.JFrame;import java.awt.*;import java.net.*;import java.io.*;/** * <p>This is a very minimalistic implemenation of a subset * of the FTP protocol. One of the design goals at Rad Inks is to keep the * size of our software as small as possible and not to not produce bloatware. * Thus this class is suitable when you do not need the full functionality * of the file transfer protocol. * </p> * * <p>Subclasses provide a more complete implementation and should be used * when you need more complete functionality. Please note that all most all * servers in wide use only implement a small subset of the FTP RFC. Thus * we see no reason to make this and our subclass a complete implementation * either.</p> * * @author Raditha Dissanayake * @version 1.13 *//** * @todo better provide support for switching between ascii and binary. */public class FTPConnection { public static int ACTIVE_MODE=1; public static int PASV_MODE=0; /** * flag - defines whether to connect in active or passive modes. */ //protected int connectMode=ACTIVE_MODE; protected int connectMode=PASV_MODE; /** * socket timeout */ protected int timeout = 60000; protected final static byte[] CRLF = {0x0d,0x0A}; protected int contentLength; /** * The FTP server that we are connecting to, the username and password that * is being used for authentication and the starting location on the folder * tree are all defined by this URL. */ protected URL location; protected OutputStream out; protected Writer writer; protected InputStream in; protected Socket sock_control; protected Socket sock_data; protected String welcome=""; protected String lastMessage; private java.io.PrintStream logWriter = System.out; public FTPConnection(){} /** * Open a connection to the given FTP URL. * example URL: ftp://user:pass@ftp.radinks.com/path/info/ * All the information needed to establish the connection including username * and password should be included in the URL. If anonymous login is used * the username and password can be omitted. * * @param location a url on the ftp server. * @throws MalformedURLException */ public FTPConnection(String location) throws MalformedURLException{ this.location = new URL(location); } /** * Login, if the {@link #location location} includes a username and password use them, * else login annonymousy. * * @return did the server accept you? * @throws IOException */ public boolean login() throws IOException { String userInfo = location.getUserInfo(); if(userInfo == null) { log("anonymous login"); return login("anonymous","pass"); } else { String parts[] = userInfo.split(":"); return login(parts[0],parts[1]); } } /** * Set current working directory to the path defined in the * {@link #location url}. * * @return success or failure * @throws IOException */ public boolean cdhome() throws IOException { String path = location.getPath(); return cwd(path); } /** * Chmod is implemened via the site command. * * @param perms the permission to apply * @param path the file name to apply the permissions to * @return success or failure. * @throws IOException */ public boolean chmod(int perms,String path)throws IOException { writeln("SITE CHMOD " + perms + " " + path); return check_reply("200"); } /** * Change Working Directory * @param dir to change to * @return success or failure. * @throws IOException */ public boolean cwd(String dir) throws IOException { writeln("CWD " + dir); return check_reply("250"); } /** * Logs into the system with the given username and password. * * @param username username * @param password password * @return succes or failure. * * @throws IOException */ public boolean login(String username,String password) throws IOException { return (user(username) && pass(password)); } /** * Open the connection to the previously defined URL given in * {@link #location}. * * @throws IOException * @throws UnknownHostException */ public void openConnection() throws IOException, UnknownHostException { sock_control = new Socket();// int port = (location.getPort() < 0) ? 21 : location.getPort(); InetSocketAddress addr = new InetSocketAddress(location.getHost(),port); System.out.println("connect to " + location.getHost() + ":" + port); sock_control.connect(addr); sock_control.setSoTimeout(timeout); in = sock_control.getInputStream(); out = sock_control.getOutputStream(); writer = new OutputStreamWriter(out); } /** * The server usually sends a 220 reply when your first * connect to it. * @throws IOException */ public void initStream() throws IOException { while(true) { if(check_reply("220-")) { // ignore the banner continue; } if(lastMessage != null && lastMessage.startsWith("220")) { if(lastMessage.indexOf("Microsoft") != -1) { RemoteFile.setServerType("MS"); } else { RemoteFile.setServerType("*nix"); } } break; } } /** * Reads in a line from the control connection. * * @return the line that we just read. * @throws IOException */ private String getLine() throws IOException { int iBufLen=4096; int i=0; byte[] buf = new byte[iBufLen]; try { for(i=0 ; i < iBufLen; i++) { buf[i] = (byte) in.read(); if(buf[i] == CRLF[1]) { break; } } }catch (IOException ex) { ex.printStackTrace(); throw (ex); } return new String(buf,0,i); } /** * Send a command to the server over the control connection. * * @param command the command to excute * @param params the parameters for the command. * @throws IOException */ private void send_command(String command, String params) throws IOException { writeln(command + " " + params); } /** * Centralize all the write operations for ease of maintenance. * * @param s the data to be sent over the control connection. * @throws IOException */ protected void writeln(String s) throws IOException { writer.write(s); writer.write("\r\n"); writer.flush(); log("> " + s); } /** * Open a data connection in active mode. Active mode requires that the * client listens for incoming connections - effectively a reversal of the * tradicational client/server relationship. * * @return a ServerSocket to listen on. * @throws IOException */ public ServerSocket port() throws IOException { ServerSocket socket = new ServerSocket(0); InetAddress localhost = sock_control.getLocalAddress(); int s_port = socket.getLocalPort(); byte[] ip = localhost.getAddress(); byte[] port = new byte[2]; port[0] =(byte) (s_port >> 8); // most significant babes port[1] =(byte) (s_port & 0x00FF); String cmd = "PORT " + makeUnsignedShort(ip[0]) + "," + makeUnsignedShort(ip[1]) + "," + makeUnsignedShort(ip[2]) + "," + makeUnsignedShort(ip[3]) + "," + makeUnsignedShort(port[0]) + "," + makeUnsignedShort(port[1]); writeln(cmd); if(check_reply("200")) { return socket; } else { return null; } } /** * Open a passive mode data connection. * * @return a client Socket * * @throws IOException */ protected Socket pasv() throws IOException { writeln("pasv"); if(check_reply("227")) { int start = lastMessage.indexOf('('); int end = lastMessage.indexOf(')'); String sockaddr = lastMessage.substring(start+1,end); String[] parts = sockaddr.split(","); /* why loop when it's only a single statement? */ String s_hostIP = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3]; /* get the port */ int port = (Integer.parseInt(parts[4]) << 8) + Integer.parseInt(parts[5]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -