我有一个 Windows MFC C++ 应用程序,它使用
CFtpFileFind::FindFile()
从(共享)服务器读取文件列表,然后使用 CFtpConnection::PutFile()
上传多个文件。当 ISP 是 CenturyLink 时,此方法有效,但当 ISP 是 Xfinity 时,此方法失败。我可以使用 CInternetSession()
读取http 文件,但无法使用 ftp 读取或写入。我可以使用 FileZilla 等 ftp 应用程序使用相同的凭据和端口号访问文件。
下面的代码遇到了这个问题。该代码不会抛出异常,并且无论 ISP 如何,所有指针看起来都有效,但当 ISP 是 Xfinity 时,它会失败,如注释中所述。
CInternetSession* pSession = nullptr;
try
{
CInternetSession* pSession = new CInternetSession(DOWNLOAD_SESSION_NAME, 1UL, 0UL, NULL, NULL, INTERNET_FLAG_DONT_CACHE);
CFtpConnection* pConnect = pSession->GetFtpConnection(L"my_ftp_url.com", L"my_username", L"my_password", 21);
CFtpFileFind finder(pConnect);
BOOL bFoundFile = finder.FindFile(_T("*")); // This returns false with Xfinity.
int iFileCount = 0;
while(bFoundFile)
{
bFoundFile = finder.FindNextFile();
iFileCount++;
}
TRACE(L"Found %d files.", iFileCount); // This returns 0 with Xfinity.
if(iFileCount > 0)
{
if(!pConnect->PutFile(L"C:\\test.txt", L"test.txt"))
{
const int iError = GetLastError(); // This returns 12003 with Xfinity.
}
}
}
catch(CException* e)
{
// Exceptions are not thrown.
}
想法?在我们更换 ISP 之前,代码运行良好。
谢谢!
解决方案是使用ftp被动模式。如此处所示,在调用 GetFtpConnection() 时为 bPassive 参数传递 true 允许使用 CenturyLink 和 Xfinity 进行 ftp 操作:
pSession->GetFtpConnection(L"my_ftp_url.com", L"my_username", L"my_password", 21, true);
如果您调用 InternetConnect() 而不是使用 MFC,请添加 INTERNET_FLAG_PASSIVE 标志,如下所示:
InternetConnect(hInternet, L"my_ftp_url.com", INTERNET_DEFAULT_FTP_PORT, L"my_username", L"my_password", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
另外,FWIW,当我没有使用被动模式时 GetLastError() 返回 12003 作为错误代码。