apache Тайм-аут соединения с клиентом FTP при подключении для удаления хоста - PullRequest
0 голосов
/ 31 марта 2020

Название дублируется, но вопрос в другом.

Я использую класс FTPClient [apache commons 3.6] для подключения к FTP-серверу [apache ftp-сервер 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 () работает, но время ожидания при входе в систему. Любые параметры для настройки здесь?

I проверил сервер с 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 
 }

1 Ответ

0 голосов
/ 01 апреля 2020

Я наконец получил ответ. Эта проблема была проблемой тайм-аута соединения, которая была разделена на 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());

Offcourse, если ваша сеть работает медленно, вам также нужен тайм-аут в коде клиента

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