当前位置 博文首页 > 猪猪_123123123123的博客:apache-net ftpclient ftp死锁的问题

    猪猪_123123123123的博客:apache-net ftpclient ftp死锁的问题

    作者:[db:作者] 时间:2021-07-19 19:25

    最近写了一个连接ftp的应用,但是由于供应商是好多年前的了,ftp 服务器没有更新,每天都有一小段时间ftp服务器无法连接.但是我的ftpclient并没有提示超时.

    这是先前的代码

    @SuppressWarnings("unused")
    	@Deprecated
    	private static boolean connectServer(String ip, int port, String username, String password, FTPClient ftpClient) {
    		/**
    		 * 1、先连接ftp服务器
    		 */
    		try {
    			ftpClient.connect(ip, port);
    			/**
    			 * 2、登陆
    			 */
    			if (!ftpClient.login(username, password)) {
    				logger.error("登陆服务器失败......");
    			}
    			// ftpClient.getSystemType();
    			/**
    			 * 使用本地的主动模式(默认为本地被动)
    			 */
    			// ftpClient.enterLocalActiveMode();
    			/**
    			 * 二进制传输
    			 */
    			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    			/*
    			 * if(FTPReply.isPositiveCompletion(ftpClient.sendCommand(
    			 * "OPTS UTF8", "ON"))) {
    			 * BaseEntity.getInstance().setLocalCharset("utf-8"); }
    			 */
    			ftpClient.enterLocalPassiveMode();// 设置被动模式
    
    			ftpClient.setControlEncoding(BaseEntity.getInstance().getLocalCharset());
    			/**
    			 * 每隔2分钟发送一次请求,没有任何意义的请求,保持连接畅通
    			 */
    			ftpClient.setControlKeepAliveTimeout(300);
    			ftpClient.setControlKeepAliveReplyTimeout(300);
    			ftpClient.setKeepAlive(true);
    
    			ftpClient.setDefaultTimeout(10000);
    			ftpClient.setConnectTimeout(10000);
    			ftpClient.setDataTimeout(10000);
    			// 外网需要设为false
    			ftpClient.setRemoteVerificationEnabled(false);
    			// ftpClient.setUseEPSVwithIPv4(true);
    		} catch (IOException e) {
    			if (ftpClient.isConnected()) {
    				try {
    					ftpClient.disconnect();
    				} catch (IOException f) {
    				}
    			}
    			e.printStackTrace();
    			logger.error("不能连接到  " + ip + ":" + port + " 服务器,或者使用账号:" + username + ",密码:" + password + " 无法登陆", e);
    			return false;
    		}
    超时都设了,而且是被动模式,显示不行.

    这是后来的代码

    private static boolean getConnect(String ip, int port, String username, String password, FTPClient ftpClient) {
    		/**
    		 * 1、先连接ftp服务器
    		 */
    		try {
    			logger.info("连接ftp服务器");
    			ftpClient.setDefaultTimeout(10000);
    			ftpClient.setConnectTimeout(10000);
    			ftpClient.setDataTimeout(10000);
    
    			ftpClient.connect(ip, port);
    			/**
    			 * 2、登陆
    			 */
    			logger.info("登录ftp服务器");
    			if (!ftpClient.login(username, password)) {
    				logger.error("登陆服务器失败......");
    			}
    			// ftpClient.getSystemType();
    			/**
    			 * 使用本地的主动模式(默认为本地被动)
    			 */
    			// ftpClient.enterLocalActiveMode();
    			/**
    			 * 二进制传输
    			 */
    			logger.info("设置ftp属性");
    			ftpClient.enterLocalPassiveMode();// 设置被动模式
    			ftpClient.setControlKeepAliveTimeout(300);
    			ftpClient.setControlKeepAliveReplyTimeout(300);
    
    			ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
    			ftpClient.setControlEncoding(BaseEntity.getInstance().getLocalCharset());
    			ftpClient.setKeepAlive(true);
    			// 外网需要设为false
    			// ftpClient.setRemoteVerificationEnabled(false);
    		} catch (IOException e) {
    			if (ftpClient.isConnected()) {
    				try {
    					ftpClient.disconnect();
    				} catch (IOException f) {
    				}
    			}
    			e.printStackTrace();
    			logger.error("不能连接到  " + ip + ":" + port + " 服务器,或者使用账号:" + username + ",密码:" + password + " 无法登陆", e);
    			return false;
    		}
    
    		return verifyFtpConnect(ftpClient);
    	}
    把三个超时放到前面去就好了,这是ftpclient的原文解释

     /**
         * Set the default timeout in milliseconds to use when opening a socket.
         * This value is only used previous to a call to
         * {@link #connect connect()}
         * and should not be confused with {@link #setSoTimeout setSoTimeout()}
         * which operates on an the currently opened socket.  _timeout_ contains
         * the new timeout value.
         * <p>
         * @param timeout  The timeout in milliseconds to use for the socket
         *                 connection.
         */
        public void setDefaultTimeout(int timeout)
        {
            _timeout_ = timeout;
        }
    意思是要把这个超时设置在connect()之前,经过测试,ok

    cs