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

📄 ftpcontrolsocket.java

📁 java编写的非常详尽的基于ftp协议的上传下载源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

         // output stream
         OutputStream os = controlSock.getOutputStream();
         writer = new OutputStreamWriter(os, encoding);
     }


     /**
      *  Get the name of the remote host
      *
      *  @return  remote host name
      */
     String getRemoteHostName() {
         InetAddress addr = controlSock.getInetAddress();
         return addr.getHostName();
     }
     
     /**
      * Set strict checking of FTP return codes. If strict 
      * checking is on (the default) code must exactly match the expected 
      * code. If strict checking is off, only the first digit must match.
      * 
      * @param strict    true for strict checking, false for loose checking
      */
     void setStrictReturnCodes(boolean strict) {
         this.strictReturnCodes = strict;
     }
     
     /**
      * Listen on all interfaces for active mode transfers (the default).
      * 
      * @param listenOnAll   true if listen on all interfaces, false to listen on the control interface
      */
     void setListenOnAllInterfaces(boolean listenOnAll) {
         this.listenOnAllInterfaces = listenOnAll;
     }
     
     /**
      * Are we listening on all interfaces in active mode, which is the default?
      * 
      * @return true if listening on all interfaces, false if listening just on the control interface
      */
     boolean getListenOnAllInterfaces() {
         return listenOnAllInterfaces;
     }
     

    /**
     *   Set the TCP timeout on the underlying control socket.
     *
     *   If a timeout is set, then any operation which
     *   takes longer than the timeout value will be
     *   killed with a java.io.InterruptedException.
     *
     *   @param millis The length of the timeout, in milliseconds
     */
    void setTimeout(int millis)
        throws IOException {

        if (controlSock == null)
            throw new IllegalStateException(
                        "Failed to set timeout - no control socket");

        controlSock.setSoTimeout(millis);
    }
    
    
    /**
     * Set a listener that handles all FTP messages
     * 
     * @param listener  message listener
     */
    void setMessageListener(FTPMessageListener listener) {
        this.messageListener = listener;
    }
    
    /**
     * Close the socket
     * 
     * @throws IOException
     */
    public void close() throws IOException {
        controlSock.close();
    }

    /**
     *  Quit this FTP session and clean up.
     */
    public void logout()
        throws IOException {

        IOException ex = null;
        try {
            writer.close();
        }
        catch (IOException e) {
            ex = e;
        }
        try {
            reader.close();
        }
        catch (IOException e) {
            ex = e;
        }
        try {
            controlSock.close();
        }
        catch (IOException e) {
            ex = e;
        }
        if (ex != null)
            throw ex;
     }
              
     /**
      *  Request a data socket be created on the
      *  server, connect to it and return our
      *  connected socket.
      *
      *  @param  active   if true, create in active mode, else
      *                   in passive mode
      *  @return  connected data socket
      */
     FTPDataSocket createDataSocket(FTPConnectMode connectMode)
         throws IOException, FTPException {

        if (connectMode == FTPConnectMode.ACTIVE) {
            return createDataSocketActive();
        }
        else { // PASV
            return createDataSocketPASV();
        }
     }        

     /**
      *  Request a data socket be created on the Client
      *  client on any free port, do not connect it to yet.
      *
      *  @return  not connected data socket
      */
	 FTPDataSocket createDataSocketActive()
        throws IOException, FTPException {

	    try {
	        int count = 0;
            int maxCount = MAX_ACTIVE_RETRY;
            if (lowPort >= 0 && highPort >= 0) {
                int range = highPort-lowPort+1;
                if (range < MAX_ACTIVE_RETRY)
                    maxCount = range;
            }
            while (count < maxCount)
            {
                count++;
                try
                {
                    // use the next port in list (or 0 by default, indicating any port number)
                    FTPDataSocket socket = newActiveDataSocket(nextPort);
                    short port = (short)socket.getLocalPort();
                    sendPORTCommand(port);                  
                    return socket;
                }
                catch (SocketException ex) 
                {
                    // check ok to retry
                    if (count < maxCount)
                    {
                        log.warn("Detected socket in use - retrying and selecting new port");
                        setNextAvailablePortFromRange();
                    }
                }
            }
            throw new FTPException("Exhausted active port retry count - giving up");
	    }
        finally {
            setNextAvailablePortFromRange();
        }        
     }       
	 
	 
     private void setNextAvailablePortFromRange() 
     {
         // keep using 0 if using OS ports
         if (lowPort < 0 && highPort < 0)
             return;

         // need to set next port to random port in range if it is 0 and we
         // get to here - means the active port ranges have been changed
         if (nextPort == 0) {            
              nextPort = lowPort + new Random().nextInt(highPort-lowPort);
         }
         else
             nextPort++;

         // if exceeded the high port drop to low
         if (nextPort > highPort)
             nextPort = lowPort;

         log.debug("Next active port will be: " + nextPort);
     }
     
     /**
      * Send the PORT command to the server
      * 
      * @param socket           data socket
      * @throws IOException
      * @throws FTPException
      */
     void sendPORTCommand(short port) 
         throws IOException, FTPException {
         
         // get the local address to which the control socket is bound.
         InetAddress localhost = controlSock.getLocalAddress();

         // send the PORT command to the server
         setDataPort(localhost, port);
     }
     
    /**
     *  Helper method to convert a byte into an unsigned short value
     *
     *  @param  value   value to convert
     *  @return  the byte value as an unsigned short
     */
    private short toUnsignedShort(byte value) {
        return ( value < 0 )
            ? (short) (value + 256)
            : (short) value;
     }

    /**
     *  Convert a short into a byte array
     *
     *  @param  value   value to convert
     *  @return  a byte array
     */
    protected byte[] toByteArray (short value) {

        byte[] bytes = new byte[2];
        bytes[0] = (byte) (value >> 8);     // bits 1- 8
        bytes[1] = (byte) (value & 0x00FF); // bits 9-16
        return bytes;
    }
    
    
    /**
     * We can force PORT to send a fixed IP address, which can be useful with certain
     * NAT configurations. Must be connected to the remote host to call this method.
     * 
     * @param forcedActiveIP     IP address to force
     */    
    void setActivePortIPAddress(String forcedActiveIP) {
        this.forcedActiveIP = forcedActiveIP;        
    }
    
    /**
     * Set the port number range for active mode
     * 
     * @param lowest        lowest port number in range
     * @param highest       highest port number in range
     */
    public void setActivePortRange(int lowest, int highest) {
        this.lowPort = lowest;
        this.highPort = highest;
        this.nextPort = lowPort;
    }
    
    /**
     * Gets the IP address bytes from an IPV4 address that is
     * a string
     * 
     * @param IPAddress   ip address such as 192.168.10.0
     * @return
     * @throws FTPException
     */
    private byte[] getIPAddressBytes(String IPAddress) 
        throws FTPException {
        
        byte ipbytes[] = new byte[4];
        int len = IPAddress.length();
        int partCount = 0;
        StringBuffer buf = new StringBuffer();
    
        // loop thru and examine each char
        for (int i = 0; i < len && partCount <= 4; i++) {
    
            char ch = IPAddress.charAt(i);
            if (Character.isDigit(ch))
                buf.append(ch);
            else if (ch != '.') {
                throw new FTPException("Incorrectly formatted IP address: " + IPAddress);
            }
    
            // get the part
            if (ch == '.' || i+1 == len) { // at end or at separator
                try {
                    ipbytes[partCount++] = (byte)Integer.parseInt(buf.toString());
                    buf.setLength(0);
                }
                catch (NumberFormatException ex) {
                    throw new FTPException("Incorrectly formatted IP address: " + IPAddress);
                }
            }
        }
        return ipbytes;
    }


    /**
     *  Sets the data port on the server, that is, sends a PORT
     *  command.
     *
     *  @param  host    the local host the server will connect to
     *  @param  portNo  the port number to connect to
     */
    protected void setDataPort(InetAddress host, short portNo)
        throws IOException, FTPException {

        byte[] hostBytes = host.getAddress();
        byte[] portBytes = toByteArray(portNo);
        
        if (forcedActiveIP != null) {
            log.info("Forcing use of fixed IP for PORT command");
            hostBytes = getIPAddressBytes(forcedActiveIP);
        }

        // assemble the PORT command
        String cmd = new StringBuffer ("PORT ")
            .append (toUnsignedShort (hostBytes[0])) .append (",")
            .append (toUnsignedShort (hostBytes[1])) .append (",")
            .append (toUnsignedShort (hostBytes[2])) .append (",")
            .append (toUnsignedShort (hostBytes[3])) .append (",")
            .append (toUnsignedShort (portBytes[0])) .append (",")
            .append (toUnsignedShort (portBytes[1])) .toString ();

        // send command and check reply
        // CoreFTP returns 250 incorrectly
        FTPReply reply = sendCommand(cmd);
        String[] validCodes = {"200", "250"};
        validateReply(reply, validCodes);
     }

     /**
      *  Request a data socket be created on the
      *  server, connect to it and return our
      *  connected socket.
      *
      *  @return  connected data socket
      */
     protected FTPDataSocket createDataSocketPASV()
         throws IOException, FTPException {

         // PASSIVE command - tells the server to listen for
         // a connection attempt rather than initiating it
         FTPReply replyObj = sendCommand("PASV");
         validateReply(replyObj, "227");
         String reply = replyObj.getReplyText();

         int[] parts = getPASVParts(reply);

         // assemble the IP address
         // we try connecting, so we don't bother checking digits etc
         String ipAddress = parts[0] + "."+ parts[1]+ "." +
             parts[2] + "." + parts[3];

         // assemble the port number
         int port = (parts[4] << 8) + parts[5];
         
         String hostIP = ipAddress;
         if (autoPassiveIPSubstitution) {
             hostIP = remoteAddr.getHostAddress();
             StringBuffer msg = new StringBuffer("Substituting server supplied IP (");
             msg.append(ipAddress).append(") with remote host IP (").append(hostIP).append(")");
             log.debug(msg.toString());

⌨️ 快捷键说明

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