2014-01-30 11 views
2

나는이 질문을 올리려고 시도해 본 다음, 성공하지 못했습니다. 아파치 공유 라이브러리를 사용하여 안드로이드에서 FTP 파일 전송을 구현하려고합니다. 통신은 명시 적 TLS 인증을 통해 이루어져야합니다. 성공적으로 로그인하고 서버 및 목록 파일에 연결할 수 있지만 파일을 가져 오거나 저장할 때마다 항상 2KB의 txt 파일에 대해서도 매우 큰 시간 제한 값이있는 시간 초과 예외가 발생합니다. 이 내 코드입니다 :이 특정 상황의 예를 찾을 수 없습니다명백한 TLS를 통해 android ftp 파일을 전송합니다.

FTPSClient ftpClient = new FTPSClient("TLS", false); 
    ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); 
KeyManagerFactory kmf = getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
kmf.init(null, null); 
KeyManager km = kmf.getKeyManagers()[0]; 
ftpClient.setKeyManager(km); 
ftpClient.setBufferSize(1024 * 1024); 
ftpClient.setConnectTimeout(900000); 
ftpClient.connect(InetAddress.getByName("server ip address"), 990); 
// Set protection buffer size 
ftpClient.execPBSZ(0); 
// // Set data channel protection to private 
ftpClient.execPROT("P"); 
ftpClient.login("user", "password"); 
ftpClient.changeWorkingDirectory("/"); 
ftpClient.setSoTimeout(900000); 
ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 
ftpClient.enterLocalPassiveMode(); 
buffIn = new BufferedInputStream(new FileInputStream(file.getAbsolutePath())); 

//this works 
FTPFile[] files = ftpClient.listFiles(); 
final OutputStream os = new FileOutputStream(finalStoragePath + "/OK.txt"); 
//this returns immediatly with false result 
boolean getResult=ftpClient.retrieveFile("OK.txt", os); 
//this always fail for timeout 
boolean result = ftpClient.storeFile(picture.getName(), buffIn); 

, 거기에 모든 예제, 나는 아무런 문제없이 달성 할 수있는 일반적인 FTP 연결하려고합니다. 당신 중 누구도 비슷한 문제가 있었습니까? 정말 해결책이 필요합니다. 최대한 빨리 프로젝트를 제공해야합니다.

감사합니다. 나는 마침내 해결책을 발견

답변

3

이 솔루션은 모든 인증서를 허용하도록 트러스트 매니저를 설정했다. 여기에 비슷한 문제가 발생하는 사람들을위한 코드는, 그것을 개선 및/또는 최적화 할 수 maby하지만 작동합니다

FTPSClient ftpClient = new FTPSClient("TLS", false); 
try { 
    TrustManager[] trustManager = new TrustManager[] { new X509TrustManager() { 
     @Override 
     public X509Certificate[] getAcceptedIssuers() { 
      return null; 
     } 

     @Override 
     public void checkClientTrusted(X509Certificate[] certs, String authType) { 
     } 

     @Override 
     public void checkServerTrusted(X509Certificate[] certs, String authType) { 
     } 
    } }; 

    ftpClient.setTrustManager(trustManager[0]); 
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    kmf.init(null, null); 
    KeyManager km = kmf.getKeyManagers()[0]; 
    ftpClient.setKeyManager(km); 
    ftpClient.setBufferSize(1024 * 1024); 
    ftpClient.setConnectTimeout(100000); 
    ftpClient.connect(InetAddress.getByName("ipaddress"), 990); 
    ftpClient.setSoTimeout(100000); 

    if (ftpClient.login("user", "password")) { 
     ftpClient.execPBSZ(0); 
     ftpClient.execPROT("P"); 
     ftpClient.changeWorkingDirectory("/"); 
     // 250 = directory succesfully changed 
     if (ftpClient.getReplyString().contains("250")) { 
      ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 
      ftpClient.enterLocalPassiveMode(); 
      BufferedInputStream buffIn = null; 

      for (File picture : pictures) { 
       buffIn = new BufferedInputStream(new FileInputStream(picture.getAbsolutePath())); 
       boolean result = ftpClient.storeFile(picture.getName(), buffIn); 
       try { 
        buffIn.close(); 
       } catch (Exception e) { 
       } 
       if (result) 
        picture.delete(); 
      } 
     } 
    } 

} catch (SocketException e) { 
    Log.e("APPTAG", e.getStackTrace().toString()); 
} catch (UnknownHostException e) { 
    Log.e("APPTAG", e.getStackTrace().toString()); 
} catch (IOException e) { 
    Log.e("APPTAG", e.getStackTrace().toString()); 
} catch (Exception e) { 
    Log.e("APPTAG", e.getStackTrace().toString()); 
} finally { 
    try { 
     ftpClient.logout(); 
    } catch (Exception e2) { 
    } 
    try { 
     ftpClient.disconnect(); 
    } catch (Exception e2) { 
    } 
} 
+0

해결책을 시도했지만 파일을 업로드하려고 할 때 오류가 발생합니다. I/System.out : javax.net.ssl.SSLException : 쓰기 오류 : ssl = 0x7f9d8c6200 : I/O 오류 시스템 호출 중, 파손 된 파이프 – Laire

1

대신 하나를 만드는 모든 인증서를 받아 라이브러리 트러스트 매니저를 추가 할 수 있습니다.

FTPSClient mFtps = new FTPSClient(); 
mFtps.setTrustManager(TrustManagerUtils.getAcceptAllTrustManager()); 
1

getAcceptAllTrustManager()는 어떤 확인이 인증서의 유효성에 대하여 수행되지 않는 것을 의미한다. 관련 사이트의 종단 간 제어가 가능하다면 괜찮을 수도 있습니다. 참조 : Trusting all certificates using HttpClient over HTTPS