使用FTPSClient上传文件遇501错误:Server cannot accept argument求助
FTPS上传文件报错
501 Server cannot accept argument(Apache Commons Net FTPSClient) 我使用Apache Commons Net的FTPSClient开发FTPS文件上传功能,通过ftpClient.isConnected()确认连接状态正常,但调用ftpClient.storeFile(file.getName(), fis)上传文件时返回false,服务器报错501 Server cannot accept argument.。
原代码片段
FTPSClient ftpClient = new FTPSClient("SSL",true); try { FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); ftpClient.configure(conf); ftpClient.connect(host,port); ftpClient.login(user, pass); System.out.println("Connected?: "+ftpClient.isConnected()); ftpClient.enterLocalPassiveMode(); String path = carpetaLocal; File directorio = new File(path); File[] ficheros = directorio.listFiles(); for (int i = 0; i < ficheros.length; i++) { File file = (ficheros[i]); FileInputStream fis = new FileInputStream(file); Client.setFileType(FTPClient.BINARY_FILE_TYPE); ftpClient.enterLocalActiveMode(); boolean res = ftpClient.storeFile(file.getName(), fis); System.out.println("File Upload Successful?: " + res); } ftpClient.disconnect(); System.out.println("Connected?: "+ftpClient.isConnected()); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); }
问题排查与解决方案
1. 修复变量名错误
代码中Client.setFileType(FTPClient.BINARY_FILE_TYPE);存在变量名错误,应该使用ftpClient实例调用方法,否则文件类型未正确设置,可能引发参数错误:
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
2. 统一传输模式,避免频繁切换
原代码先调用enterLocalPassiveMode(),循环内又切换为enterLocalActiveMode(),FTPS传输模式频繁切换容易导致服务器无法处理参数。推荐统一使用被动模式(适配大部分防火墙环境):
删除循环内的ftpClient.enterLocalActiveMode();,保留登录后的ftpClient.enterLocalPassiveMode();。
3. 增加操作状态检查
仅通过isConnected()无法确认登录和操作是否真的成功,需检查FTP回复码:
// 连接后检查回复 int connectReply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(connectReply)) { System.err.println("连接失败,回复码:" + connectReply); ftpClient.disconnect(); System.exit(1); } // 登录后检查结果 boolean loginSuccess = ftpClient.login(user, pass); int loginReply = ftpClient.getReplyCode(); if (!loginSuccess || !FTPReply.isPositiveCompletion(loginReply)) { System.err.println("登录失败,回复码:" + loginReply); ftpClient.disconnect(); System.exit(1); }
4. 启用数据连接SSL加密
部分FTPS服务器要求数据连接也使用SSL加密,需添加以下配置:
ftpClient.execPBSZ(0); ftpClient.execPROT("P");
5. 优化资源管理与错误排查
- 使用
try-with-resources自动关闭文件输入流,避免资源泄漏; - 打印服务器完整回复字符串,获取更详细的错误信息:
try (FileInputStream fis = new FileInputStream(file)) { boolean res = ftpClient.storeFile(file.getName(), fis); System.out.println("文件 " + file.getName() + " 上传成功? " + res); System.out.println("服务器回复: " + ftpClient.getReplyString()); } catch (IOException e) { System.err.println("上传文件失败: " + e.getMessage()); }
修正后的完整代码
FTPSClient ftpClient = new FTPSClient("SSL", true); try { FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT); ftpClient.configure(conf); ftpClient.connect(host, port); // 检查连接回复 int connectReply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(connectReply)) { System.err.println("连接服务器失败,回复码:" + connectReply); ftpClient.disconnect(); System.exit(1); } // 登录并验证结果 boolean loginSuccess = ftpClient.login(user, pass); int loginReply = ftpClient.getReplyCode(); if (!loginSuccess || !FTPReply.isPositiveCompletion(loginReply)) { System.err.println("登录失败,回复码:" + loginReply); ftpClient.disconnect(); System.exit(1); } System.out.println("已连接: " + ftpClient.isConnected()); // 启用被动模式 ftpClient.enterLocalPassiveMode(); // 设置二进制文件类型 ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 启用数据连接SSL加密 ftpClient.execPBSZ(0); ftpClient.execPROT("P"); String path = carpetaLocal; File directorio = new File(path); File[] ficheros = directorio.listFiles(); if (ficheros == null) { System.err.println("指定本地目录不存在或无法访问"); return; } for (File file : ficheros) { if (file.isFile()) { try (FileInputStream fis = new FileInputStream(file)) { boolean res = ftpClient.storeFile(file.getName(), fis); System.out.println("文件 " + file.getName() + " 上传成功? " + res); System.out.println("服务器回复: " + ftpClient.getReplyString()); } catch (IOException e) { System.err.println("上传文件 " + file.getName() + " 失败: " + e.getMessage()); } } } ftpClient.logout(); ftpClient.disconnect(); System.out.println("已断开连接: " + !ftpClient.isConnected()); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); }
内容的提问来源于stack exchange,提问作者Oscar Mauricio Gomez Acevedo
相关产品推荐
相关产品推荐

