apache FTP 连接删除主机时客户端连接超时
apache FTP Client connection timeout when connecting to remove host
标题重复但问题不同
我正在使用 FTPClient[apache commons 3.6] class 连接到 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
}
我终于得到了答案。这个问题是一个连接超时问题,分为两部分
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
标题重复但问题不同
我正在使用 FTPClient[apache commons 3.6] class 连接到 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
}
我终于得到了答案。这个问题是一个连接超时问题,分为两部分
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