Java 通过Apache Ftpserver实现ftp服务的时候我想实现文件不落地直接拿到文件流发走,而ftp的被动模式需要服务端开启一个TCP监听让客户端连接,服务器已经开启了服务,但是客户端始终连接不上是什么情况。
2024-10-18 10:53:31 31447 2 状态: 已登录
2024-10-18 10:53:31 31447 2 状态: 开始上传 /Users/tanghanlin/Desktop/O-v1.0.docx
2024-10-18 10:53:31 31447 2 命令: CWD /
2024-10-18 10:53:31 31447 2 响应: 250 Directory changed to /
2024-10-18 10:53:31 31447 2 命令: TYPE I
2024-10-18 10:53:31 31447 2 响应: 200 Command TYPE okay.
2024-10-18 10:53:31 31447 2 命令: PASV
2024-10-18 10:53:31 31447 2 响应: 227 Entering Passive Mode (127,0,0,1,215,26)
2024-10-18 10:53:31 31447 2 命令: STOR O-v1.0.docx
就一直卡在这里。
```java
package com.slorgs.server;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.command.AbstractCommand;
import org.apache.ftpserver.command.CommandFactoryFactory;
import org.apache.ftpserver.ftplet.*;
import org.apache.ftpserver.impl.*;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.ClearTextPasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author hanlin.tang
*/
public class FtpServer {
private static final Logger log = LoggerFactory.getLogger(FtpServer.class);
public static void start() {
try {
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
factory.setPort(2221);
serverFactory.addListener("default", factory.createListener());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
userManagerFactory.setFile(new File("/Users/tanghanlin/IdeaProjects/file_transfer_demo/src/main/resources/myusers.properties"));
userManagerFactory.setPasswordEncryptor(new ClearTextPasswordEncryptor());
UserManager userManager = userManagerFactory.createUserManager();
serverFactory.setUserManager(userManager);
CommandFactoryFactory commandFactoryFactory = new CommandFactoryFactory();
commandFactoryFactory.addCommand("STOR", new CustomStoreCommand2());
serverFactory.setCommandFactory(commandFactoryFactory.createCommandFactory());
org.apache.ftpserver.FtpServer server = serverFactory.createServer();
server.start();
} catch (Exception ex) {
log.error("Error occurred: {}", ex.getMessage(), ex);
}
}
public static class CustomStoreCommand2 extends AbstractCommand {
@Override
public void execute(FtpIoSession session, FtpServerContext context, FtpRequest request) throws FtpException {
ServerSocket serverSocket = null;
Socket clientSocket = null;
try {
InetSocketAddress localAddress1 = (InetSocketAddress) session.getLocalAddress();
serverSocket = new ServerSocket(0, 0, localAddress1.getAddress());
int port = serverSocket.getLocalPort();
log.info("Open port: {}", port);
clientSocket = serverSocket.accept();
InputStream dataInputStream = clientSocket.getInputStream();
byte[] buffer = new byte[4096];
int bytesRead;
try (OutputStream o = Files.newOutputStream(Paths.get("/Users/tanghanlin/Desktop/sftp/sss.txt"))) {
while ((bytesRead = dataInputStream.read(buffer)) != -1) {
o.write(buffer, 0, bytesRead);
o.flush();
}
}
session.write(LocalizedFtpReply.translate(session, request, context,
FtpReply.REPLY_226_CLOSING_DATA_CONNECTION, "STOR", null));
} catch (Exception e) {
log.error("Error occurred during STOR: {}", e.getMessage(), e);
} finally {
closeResources(serverSocket, clientSocket);
}
}
private void closeResources(ServerSocket serverSocket, Socket clientSocket) {
try {
if (clientSocket != null) clientSocket.close();
if (serverSocket != null) serverSocket.close();
} catch (IOException e) {
log.error("Error closing resources: {}", e.getMessage());
}
}
}
}
```