当我试图在FTP服务器中存储一个文件时,我面临一个问题。当试图将文件上载到FTP服务器时,将创建该文件,但其内容不会被复制。
上下文
我们使用以下配置来使用lftp访问FTP服务器。我无法更改此配置,也不知道为什么禁用验证证书时使用FTPS。
# FTPS_OPTIONS:
set ssl:verify-certificate/testhostname no;
set ftp:ssl-protect-data yes;
set ftp:passive-mode on;我需要存储Java应用程序中的某些文件。我在使用。实现的代码如下所示:
@Autowired
public FtpService() {
ftpsClient = new FTPSClient();
ftpsClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
}
public void uploadFile(String ftpHost, File tempFile, String destination, String filename)
throws UploadException {
ftpsClient.connect(ftpHost, 990);
ftpsClient.execPBSZ(0);
ftpsClient.execPROT("P");
ftpsClient.enterLocalPassiveMode();
ftpsClient.setKeepAlive(true);
ftpsClient.setControlKeepAliveTimeout(3000);
if(ftpsClient.login("user", "password")) {
try (InputStream fileStream = new FileInputStream(tempFile)) {
if (!ftpsClient.changeWorkingDirectory(destination)) {
throwUploadException("Destination directory not available in FTP server");
}
boolean saved = ftpsClient.storeFile(filename, fileStream);
// Following code is not executed since the exception is thrown in the previous line
if (!saved) {
throwUploadException("Unable to save file in FTP server");
}
log.info("Saved FTP file: {}/{}", destination, filename);
}
catch (UploadException | IOException e)
{
throwUploadException(e.getMessage());
}
finally
{
ftpsClient.disconnect();
if (!tempFile.delete()) {
log.warn("Unable to delete '{}' file", tempFile.getAbsolutePath());
}
}
}
}问题
我从一个FTPClient (非FTPSClient)开始,但这样我无法登录。
目前(FTPSClient),I可以
directory
中的工作
I不能
org.apache.commons.net.io.CopyStreamException: IOException在复制时被捕获。原因: javax.net.ssl.SSLProtocolException:软件导致连接中断:套接字写入错误
listFiles()/listDirectories():执行此命令时,所获得的列表始终为空。日志记录的用户在整个FTP服务器中拥有所有必需的权限。
下面是FTP的日志(请注意,我在括号之间将命令翻译成英文),对应于前面显示的代码,这会引发前面提到的异常:
er: testhostname:990
USER *******
331 Usuario testuser OK. Clave requerida ( = User testuser OK. Password required)
PASS *******
230 OK. El directorio restringido actual es / ( = OK. The current restricted directory is /)
CWD /test/upload
250 OK. El directorio actual es /test/upload ( = Ok. The current directory is /test/upload)
PASV
227 Entering Passive Mode (<numbers...>)
[Replacing PASV mode reply address <ip_address> with testhostname]
STOR dummyfile.txt
150 Conexi├│n de datos aceptada ( = Data connection accepted)如果还有什么需要改进的地方,请告诉我。谢谢你的帮忙!
发布于 2022-07-22 14:24:31
在python连接到FTPS服务器时,我也遇到了类似的问题。错误是服务器要求数据通道会话与控制通道会话相同(重用会话)。解决方案是覆盖其中一种方法来做到这一点。
您可以测试扩展FTPClient.java并重写下一个方法:
@Override
protected void _prepareDataSocket_(final Socket socket) {
if(preferences.getBoolean("ftp.tls.session.requirereuse")) {
if(socket instanceof SSLSocket) {
// Control socket is SSL
final SSLSession session = ((SSLSocket) _socket_).getSession();
if(session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
context.setSessionCacheSize(preferences.getInteger("ftp.ssl.session.cache.size"));
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method putMethod = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
putMethod.setAccessible(true);
Method getHostMethod;
try {
getHostMethod = socket.getClass().getMethod("getPeerHost");
}
catch(NoSuchMethodException e) {
// Running in IKVM
getHostMethod = socket.getClass().getDeclaredMethod("getHost");
}
getHostMethod.setAccessible(true);
Object peerHost = getHostMethod.invoke(socket);
putMethod.invoke(cache, String.format("%s:%s", peerHost, socket.getPort()).toLowerCase(Locale.ROOT), session);
}
catch(NoSuchFieldException e) {
// Not running in expected JRE
log.warn("No field sessionHostPortCache in SSLSessionContext", e);
}
catch(Exception e) {
// Not running in expected JRE
log.warn(e.getMessage());
}
}
else {
log.warn(String.format("SSL session %s for socket %s is not rejoinable", session, socket));
}
}
}
}我在这里找到了这个https://stackoverflow.com/a/32404418/19599290解决方案:
https://stackoverflow.com/questions/73065400
复制相似问题