-
-
Notifications
You must be signed in to change notification settings - Fork 35
Open
Description
Hi, I have some question with Function (directoryContent , upload, download) , in the three Function, you use Socket Object To dataSocket.
final Socket dataSocket = await Socket.connect(_socket.host, iPort);
but I use FTPS, this is Error, I try chang some code , I think solve the error with use RawSecureSocket , this is demo:
Future<List<FTPEntry>> directoryContent({String? path}) async {
// Enter passive mode
FTPReply response = await _socket.openDataTransferChannel();
String listCmd = path != null ? "LIST $path" : "LIST";
_socket.sendCommandWithoutWaitingResponse(listCmd);
// Data transfer socket
int iPort = Utils.parsePort(response.message, _socket.supportIPV6);
SecurityContext context = SecurityContext.defaultContext;
RawSecureSocket dataSocket = await RawSecureSocket.connect(
_socket.host,
iPort,
timeout: Duration(seconds: _socket.timeout),
context: context,
onBadCertificate: (certificate) => true,
);
response = await _socket.readResponse();
bool isTransferCompleted = response.isSuccessCode();
if (!isTransferCompleted && response.code != 125 && response.code != 150) {
throw FTPConnectException('Connection refused. ', response.message);
}
final completer = Completer<List<FTPEntry>>();
List<FTPEntry> lstFTPEntries = <FTPEntry>[];
List<int> lstDirectoryListing = [];
bool isStreamDone = false; // 标记流是否已处理完成
String dataString ="";
// 获取订阅对象
final subscription = dataSocket.listen((RawSocketEvent event) {
print("event: $event");
if (event == RawSocketEvent.read) {
var data = dataSocket.read();
if (data != null) {
lstDirectoryListing.addAll(data);
String subDataString = utf8.decode(data);
dataString = dataString + subDataString;
print(dataString);
}
} else if (event == RawSocketEvent.closed) {
isStreamDone = true; // 流自然关闭时标记
dataSocket.close();
}
}, onError: (error) {
isStreamDone = true; // 出错时也标记
if (!completer.isCompleted) completer.completeError(error);
});
// 关键:等待asFuture(),但设置超时强制唤醒,避免无限阻塞
await Future.any([
subscription.asFuture(), // 正常等待流关闭
Future.delayed(Duration(seconds: 10), () {
// 超时未关闭,手动标记完成
isStreamDone = true;
print("Stream timeout, forcing completion");
}),
]);
// 无论流是自然关闭还是超时,都完成completer
if (!completer.isCompleted) {
completer.complete(lstFTPEntries);
}
// 此时一定能执行到这里
final entries = await completer.future;
// 解析逻辑保留
dataString.split('\n').forEach((line) {
if (line.trim().isNotEmpty) {
lstFTPEntries.add(
FTPEntry.parse(line.replaceAll('\r', ""), _socket.listCommand),
);
}
});
await dataSocket.close();
return entries;
}
zhe code have some timeout error, you need chang it.
I hope the code help for you.
Metadata
Metadata
Assignees
Labels
No labels