2016-07-13 32 views
0

JAVAでFTPを使用してファイルを転送しています。 私はFTPClientFTPServerをApacheから使用しています。しかし、特定の環境では、ファイルが転送されないことがあります。 enterLocalPassiveModeメソッドをFTPClientからログインメソッド呼び出しの前に呼びますが、ファイルが転送されないことがあります。FTPを使用してファイルを転送する際の問題Apache Javaの実装

  1. storeFileメソッドは "false"を返します。
  2. getReplyStringメソッドは、 "200 Command TYPE okay"を返します。
  3. リストメソッドは "227"を返します。

ファイルが正常に転送されます。

  1. リスト方法は150
  2. を返しgetReplyString方法は「大丈夫150のファイルの状態を、データ接続をオープンしよう」を返します。

クライアントコード:

 this.getFtpClientUtil().connect(settingsService.getServer(), settingsService.getFtpServerCommandChannelPort()); 

     int reply = this.getFtpClientUtil().getReplyCode(); 

     if (!FTPReply.isPositiveCompletion(reply)) { 
      logger.error("Fail to connect to FTP Server"); 
      this.getFtpClientUtil().disconnect(); 
      isConnect = false; 
      return false; 
     } 

     logger.info("FTP Server connected successfully"); 
     this.getFtpClientUtil().enterLocalPassiveMode(); 
     isConnect = this.getFtpClientUtil().login(settingsService.getftpUsername(), settingsService.getftpPassword()); 

サーバコード:

 // Data Configuration 
     this.dataConfigurationFactory = new DataConnectionConfigurationFactory(); 
     dataConfigurationFactory.setPassiveAddress(this.ipAddress); 
     dataConfigurationFactory.setPassiveExternalAddress(this.ipAddress); 
     dataConfigurationFactory.setPassivePorts(this.settingsService.getFtpServerTransferChannelPort()); 

     // Listener 
     listenerFactory = new ListenerFactory(); 
     listenerFactory.setPort(this.settingsService.getFtpServerCommandChannelPort()); 
     listenerFactory.setDataConnectionConfiguration(dataConfigurationFactory.createDataConnectionConfiguration()); 

     // Desliga SSL 
     listenerFactory.setImplicitSsl(false); 

     // User 
     PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory(); 
     UserManager um = userManagerFactory.createUserManager(); 

     this.serverFactory = new FtpServerFactory(); 
     serverFactory.addListener("default", listenerFactory.createListener()); 
     serverFactory.setUserManager(um); 

     UserFactory userFactory = new UserFactory(); 
     userFactory.setName(this.settingsService.getftpUsername()); 
     userFactory.setPassword(this.settingsService.getftpPassword()); 
     userFactory.setMaxIdleTime(60); 

     final String absolutePath = this.settingsService.getftpHomeDirectory(); 

     userFactory.setHomeDirectory(absolutePath); 
     userFactory.setAuthorities(Arrays.asList((Authority) new WritePermission())); 

     User user = userFactory.createUser(); 
     um.save(user); 

     // Connection Config 
     connectionConfigFactory = new ConnectionConfigFactory(); 
     connectionConfigFactory.setAnonymousLoginEnabled(false); 
     connectionConfigFactory.setMaxLogins(100); 
     serverFactory.setConnectionConfig(connectionConfigFactory.createConnectionConfig()); 

これはファイアウォールの問題ですか?

Iが設定しようとしたパッシブポートは、DataConnectionConfigurationFactoryクラスからsetPassivePorts方法を使用して、サーバ側での範囲が、問題は継続します。

クライアント側でポート範囲を設定するフォームはありますか。 接続が実際にパッシブモードを使用しているかどうかを確認するにはどうすればよいですか?

ありがとうございます。

+1

投稿を編集し、問題を引き起こす最小限のコードセットを含めます。 – Mike

+1

また、javaコマンドラインに-Djavax.net.debug = allを追加することもできます。これにより、ネットワークトラフィックが表示されます – Mike

+0

コードと質問を破棄しないでください。 –

答えて

0

これはファイアウォールの問題ですか?

これらの場合、アプリケーションを接続できる範囲のポートをテストまたは設定するには、ファイアウォールをオフにするのが正しい方法です。しかし、プロダクション環境では、これはオプションではありませんでした。だから私が知っている唯一のことは、開発環境でうまく動作し、生産環境で問題が発生するということです。私の仮定は、ファイアウォールがポートをブロックしているということです。

クライアント側でポート範囲を設定するフォームはありますか。接続が実際にパッシブモードを使用しているかどうかを確認するにはどうすればよいですか?

ローカルポート(接続上で設定することができる

)FTPClientから方法:

this.getFtpClientUtil().connect(settingsService.getServer(), settingsService.getFtpServerCommandChannelPort(), 
       InetAddress.getLocalHost(), getLocalPort()); 

、接続の2つの方法でパッシブモードを使用しているかどうかを確認することができます:

  1. パッシブモードが使用されていない場合、FTPClientのgetPassivePort()メソッドは-1を返します。
  2. 質問では、FTPClientのlist()メソッドが227コードを返すと述べました。このコードは、パッシブモードが使用中であることも示しています。私はこのコードが間違いだと思った。本当に起こったのはパッシブモードに入った後のエラーでしたが、以前のコマンドのコードが返されました。

ローカルポートを設定しても問題は解決されませんでした。おそらく、私が設定しているローカルポートはコマンドチャネルのためだけです。転送チャネルは依然としてクライアント側でランダムなポートを使用します。解決策は、ファイルを再度転送しようとしています。転送が失敗した場合は、クライアントを切断してから、もう一度他のポートを使用してクライアントに接続し、再度ファイルを転送しようとします。すべてのテストで、ファイルは2回目に正常に転送されました。移籍が失敗した場合は3回試行します。

クライアントを再び接続するとき、同じポートが使用された場合、javaは "java.net.BindException:Address already in use"をスローする可能性があります。クライアントを切断した後も、ポートはしばらくの間ロックされ続けます。この場合、接続する前にポートが使用可能かどうかを確認し、必要に応じて別のポートにクライアントを接続しようとします。