public static FTPClient getFTPClient() {
    FTPClient client = ftpClientThreadLocal.get();
    if (client != null && client.isConnected()) {
      return client;
    }
    ftpClientThreadLocal.remove();
    FTPClient ftpClient = new FTPClient(); // 创建ftpClient
    ftpClient.setControlEncoding("UTF-8"); // 设置字符编码
    Boolean isConnect = connectFtp(ftpClient);

    ftpClient.enterLocalPassiveMode();
    try {
      ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
      ftpClient.setSoTimeout(1000 * 30);
    } catch (Exception e) {
      e.printStackTrace();
    }
    // 得到返回答复码
    int reply = ftpClient.getReplyCode();

    if (!FTPReply.isPositiveCompletion(reply)) {
      try {
        ftpClient.disconnect();
      } catch (IOException e) {
        e.printStackTrace();
      }

    } else {
      ftpClientThreadLocal.set(ftpClient);
    }
    return ftpClient;
  }
  public void run() {
    try {
      FTPClient c = new FTPClient();
      c.configure(ftpConfig);

      logger.debug("Trying to connect");
      c.connect("127.0.0.1", 21211);
      logger.debug("Connected");

      c.setSoTimeout(5000);

      if (!FTPReply.isPositiveCompletion(c.getReplyCode())) {
        logger.debug("Houston, we have a problem. D/C");
        c.disconnect();
        throw new Exception();
      }

      if (c.login("drftpd", "drftpd")) {
        logger.debug("Logged-in, now waiting 5 secs and kill the thread.");
        _sc.addSuccess();
        Thread.sleep(5000);
        c.disconnect();
      } else {
        logger.debug("Login failed, D/C!");
        throw new Exception();
      }
    } catch (Exception e) {
      logger.debug(e, e);
      _sc.addFailure();
    }

    logger.debug("exiting");
  }
  @Override
  public void upload(UploadRequest uploadRequest) {
    ServerInfo serverInfo = uploadRequest.getServerInfo();
    String host = serverInfo.getHost();

    if (uploadRequest.isUseProxy()) {
      initializeProxy(host);
    }
    int attemptCount = 0;
    while (true) {
      try {

        login(serverInfo.getHost(), serverInfo.getLogin(), serverInfo.getPassword());

        try {
          ftpClient.setSoTimeout(DEFAULT_SOCKET_TIMEOUT);
        } catch (SocketException e) {
          LOGGER.error("socket exception: {} {}", e.getMessage(), e.getStackTrace());

          throw new RuntimeException("socket exception: " + e.getMessage());
        }

        String prefixDirectory = serverInfo.getPrefix();
        if (prefixDirectory != null) {
          ftpClient.changeWorkingDirectory(prefixDirectory);
        }

        File directory = new File(uploadRequest.getUploadDir());
        uploadDir(directory);

        ftpClient.logout();
        break;

      } catch (IOException e) {
        LOGGER.error("i/o error: {}, retrying", e.getMessage());

        attemptCount++;

        if (attemptCount > 5) {
          LOGGER.debug("choosing another proxy after 5 attempts");
          initializeProxy(host);

          attemptCount = 0;
        }
      } finally {
        if (ftpClient.isConnected()) {
          try {
            ftpClient.disconnect();
          } catch (IOException ioe) {
            // do nothing
          }
        }
      }
    }
  }