【问题标题】:apache FTP Client connection timeout when connecting to remove host连接到删除主机时apache FTP客户端连接超时
【发布时间】:2020-03-31 18:12:56
【问题描述】:

标题是重复的,但问题不同。

我正在使用 FTPClient[apache commons 3.6] 类连接到由代码启动的 FTP Server[apache ftp server 1.1.1 jar 文件]。此 FTP 服务器配置如下

  FtpServerFactory serverFactory = new FtpServerFactory();

  ListenerFactory factory = new ListenerFactory();
  factory.setServerAddress("/*IP Address*/");//The IPV4 Address Of My System
  factory.setPort(8001);  
  serverFactory.addListener("default",listener=factory.createListener());

   PropertiesUserManagerFactory userFactory=new PropertiesUserManagerFactory();
   userFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
   BaseUser baseUser=new BaseUser();
   baseUser.setName("Test");
   baseUser.setPassword("123");
   baseUser.setEnabled(true);
   baseUser.setHomeDirectory("E:/Test Data");
   baseUser.setAuthorities(Arrays.asList(new WritePermission()));
   UserManager uManager=userFactory.createUserManager();
   serverFactory.setUserManager(uManager);      

  ftpServer=serverFactory.createServer();
  ftpServer.start();

这是我连接到此服务器的方式

FTPClient client=new FTPClient();
client.connect("/*Same IP Address As Server*/",8001);

client.enterLocalPassiveMode();

client.logIn("Test","123");

当服务器和客户端都在同一个系统中时,代码可以正常工作,但是当服务器是远程主机时,我在登录时得到“ConnectionTimedOutException”

client.logIn("Test","123"); //It Throws Timeout here

奇怪的是 connect() 工作但登录时超时。这里有 tweek 的参数吗?

我使用 FTPClient gui FileZela 测试了服务器,当服务器在删除系统中但在同一系统中工作时,它给了我同样的错误 https://filezilla-project.org/download.php?type=client

这是我的连接代码的堆栈跟踪

java.net.SocketTimeoutException: connect timed out
    at java.base/java.net.PlainSocketImpl.waitForConnect(Native Method)
    at java.base/java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:107)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
    at java.base/java.net.Socket.connect(Socket.java:591)
    at org.apache.commons.net.SocketClient._connect(SocketClient.java:243)
    at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)

编辑:

我调整了一些参数,现在我可以登录到我必须更改以下参数的远程服务器

 client.setSoTimeout(5000);   //Time To Wait For Login Operation(in milliseconds)
 client.setControlKeepAliveTimeout(1); //Time Interval to send keep alive messages(in seconds)
 client.setControlKeepAliveReplyTimeout(5000);// Time to wait for an keep alive response message (in milliseconds)

但是现在我在上传任何数据时连接超时

 try(OutputStream toFile=client.storeFileStream("File.txt"))
 {
  toFile.write("Just Some Small Text".getBytes());
  toFile.close();
 }

 if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
 {
  String[] replies = ftpClient.getReplyStrings();
  if (replies != null && replies.length > 0) 
  {
   StringBuilder builder=new StringBuilder();
   for(String aReply : replies){builder.append(aReply).append(" ");}
   JOptionPane.showMessageDialog(null,builder.toString());
  } 

  //The server replies here are connection timeout no exception is thrown 
 }

【问题讨论】:

  • 您确定远程服务器上的 8001 端口上有一个 ftp 服务器正在侦听吗?
  • 8001端口是不是被防火墙屏蔽了?
  • 您能否使用与您的 Java 客户端代码在同一台机器上运行的任何 (GUI) FTP 客户端连接到您的服务器?
  • 没有防火墙阻止我的端口,因为在我遇到连接被拒绝异常之前就是这种情况,通过禁用它来解决。此外,服务器正在侦听端口 8001,因为 connect () 有效,但 login() 无效,如果我输入不正确的用户名/密码,它会立即返回不正确的状态代码,但使用正确的凭据会超时。是的,当客户端和服务器在同一台机器上时,此代码有效
  • 我在问,您是否可以使用运行在同一服务器上的任何 (GUI) FTP 客户端(不是您的代码) 连接到您的服务器机器作为您的 Java 客户端代码(不在服务器机器上)

标签: java ftp apache-commons


【解决方案1】:

我终于得到了答案。这个问题是连接超时问题,分为2部分

Q1) 登录时超时

Ans) 只需告诉 FTP 客户端稍等片刻,并使用特殊控制消息保持连接处于活动状态

这是代码示例

client.setConnectTimeout(5000);  //5000 ms to wait 
client.connect(ip,port);
if(!FTPReply.isPositiveCompletion(client.getReplyCode()))
{
 client.disconnect();
 return;
}
client.enterLocalPassiveMode(); //This Solves Part 2 Of My Problem

//These 3 lines of code are what solved my login problem
{
client.setSoTimeout(5000);//Wait Atleast 5 seconds for login
client.setControlKeepAliveTimeout(1);//Send An Keep Alive Message every second
client.setControlKeepAliveReplyTimeout(5000);//Wait atleast 5 seconds to respond to my KeepAlive messages
}
boolean success=client.login(fields[6].getText(),fields[7].getText());
if(!success)
{
 client.disconnect();
 return;
}

Q2)上传数据到服务器超时

Ans)这是一个服务器问题。原来我必须手动为客户端分配被动端口以发送数据,然后在我的路由器设置中端口转发它们

   ListenerFactory factory = new ListenerFactory();
   factory.setServerAddress("localhost");
   factory.setPort(8000);  


//And This Is What solved my Data timeout problem     
{
       DataConnectionConfigurationFactory dfFactory=new   DataConnectionConfigurationFactory();
       dfFactory.setPassivePorts("8001-8005");//I Port Forward These data ports on my router web page and disable firewall for them
       factory.setDataConnectionConfiguration(dfFactory.createDataConnectionConfiguration());
}

       serverFactory.addListener("default",factory.createListener());

当然,如果您的网络很慢,您的客户端代码也需要超时

 client.setSoTimeout(10000);//Wait 10 seconds for upload to complete
 client.setDataTimeout(10000);//Timeout if no data transfer for 10 seconds

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 2013-03-13
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多