|
This is a great inspiring article. I am pretty much pleased with your good work. You put really very helpful information. Keep it up once again.
|
|
|
|
|
thanks a lot for this great article !
|
|
|
|
|
hi, i found a problem when i use the code as follow
nsFTP::CFTPClient m_LocalFTPClient;
nsFTP::CLogonInfo LogonInfo;
if (!m_LocalFTPClient.IsConnected())
{
LogonInfo.SetHost(szSVRIP, 21, szUserName, szPassWD, static_cast<LPCTSTR>(""));
if (m_LocalFTPClient.Login(LogonInfo))
{
nsFTP::TSpFTPFileStatusVector list;
m_LocalFTPClient.List("/", list);
}
}
when i comment out "m_LocalFTPClient.List("/", list);" there is no resource leak,otherwise
the process's memory is increased by 4k once the code is invoked, could anyone come aross
this problem?
|
|
|
|
|
because it was intercepted by your firewall. go to set the firewall allow the connect.
|
|
|
|
|
how to download all files with filename matching using c++ from an ftp server
thanks
|
|
|
|
|
In method
int CFTPClient::FileModificationTime(const tstring& strPath, tstring& strModificationTime) const
Change line 1676 (iPos > -1) to the below
if( iPos != tstring::npos ) // instead of (iPos > -1)
Leaving to (iPos > -1) is not working properly with the compiler I use, it always fails. Since -1 for unsigned is also the biggest possible number.
|
|
|
|
|
In BlockingSocket.cpp function
void CBlockingSocket::Create(int nType /* = SOCK_STREAM */)
Had to change
if( (m_hSocket=socket(AF_INET, nType, 0)
to
if( (m_hSocket=socket(AF_INET, nType, IPPROTO_TCP)
Otherwise the socket never received a response.
|
|
|
|
|
Hello.
I can't compile the code.
I'm getting those errors.
Cannot open include file: stdafx.h
This error occures in those files:
BlockingSocket.cpp line 8
FTPClient.cpp line 49
FTPDataTypes line 16
FTPFIleState.cpp line 16
FTPListPare line 29
|
|
|
|
|
The stdafx.h/stdafx.cpp files are Microsoft specific extensions.
You need to open FTPexample.sln using Microsoft Visual Studio in order to build the project without code changes.
If you use another compiler and linker (like gcc) then you need to port the code for your environment.
Please google "porting Visual Studio projects to XYZ....".
|
|
|
|
|
Hi otom,
I try to retrieve all folders and files on the ftp-server and an instance of CFTPClient runs in a thread. but i get always a problem when excuting List(), just like this:
nsFTP::TSpFTPFileStatusVector list;
if (!client.List(url.toStdWString(), list)) { .... }
so the thread is blocked... as i debugged, i saw that occurred in the function
CFTPClient::OpenActiveDataConnection(...) {
...
if( !apSckServer->Accept(sckDataConnection, sockAddrTemp) ) {
...
}
and in the function
bool CBlockingSocket::Accept(...) {
...
pConnect->m_hSocket = accept(m_hSocket, psa, &nLengthAddr);
...
}
Calling of accept(m_hSocket, psa, &nLengthAddr) returns never!
this phenomenon occurs at some subfolders on the server that i have access to them.
any idea? thank you
aurora
|
|
|
|
|
Have you more than one CFTPClient connection to the server open? The list command opens a data connection on the server. Sometimes servers do not allow to open more than one data connection from a client at the same time.
Maybe there is a bug in the posted version. I am going to release a new version soon.
|
|
|
|
|
Thank you Otom
Danke!
No. there is only one CFTPClient running. here is my code, very sample:
#include "stdafx.h"
#include "cstring"
typedef struct node_s {
std::wstring name;
std::wstring path;
int state;
} node_t;
bool itr_url(nsFTP::CFTPClient& client, const node_t& node)
{
if (node.name.empty()) {
return false;
}
nsFTP::TSpFTPFileStatusVector list;
if (!client.List(node.path, list)) {
return false;
}
printf("scanning %ls \n", node.name.c_str());
for(nsFTP::TSpFTPFileStatusVector::iterator it = list.begin();
it != list.end(); ++it) {
if ((*it)->IsCwdPossible()) { //this is a folder
node_t n;
n.name = (*it)->Name().c_str();
n.path = node.path + _T("/") + n.name;
n.state = 0;
if (!itr_url(client, n)) return false;
}
}
return true;
}
bool itr_url(nsFTP::CFTPClient& client, const std::wstring path)
{
nsFTP::TSpFTPFileStatusVector list;
if (!client.List(path, list)) return false;
printf("scanning %ls \n", path.c_str());
for(nsFTP::TSpFTPFileStatusVector::iterator it = list.begin();
it != list.end(); ++it) {
if ((*it)->IsCwdPossible()) { //this is a folder
node_t n;
n.name = (*it)->Name().c_str();
n.path = path + _T("/") + n.name;
n.state = 0;
if (!itr_url(client, n)) { return false; }
}
}
if (client.IsConnected()) client.Logout();
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
int port_number = 21;
nsFTP::CFTPClient ftpClient;
nsFTP::CLogonInfo logonInfo(_T("214.25.77.227"), 21,
_T("test"), _T("Q+683bjM"));
// Initialize use of Winsock DLL by a process
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
if (LOBYTE(wsaData.wVersion) != 2 ||
HIBYTE(wsaData.wVersion) != 2) {
printf("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return 1;
} else printf("The Winsock 2.2 dll was found okay\n");
ftpClient.Login(logonInfo);
itr_url(ftpClient, _T("./content"));
ftpClient.Logout();
WSACleanup();
return 0;
}
if you have many subfolders/files under ./content, you can see that it not work.
and you can also see that the processing of List() becomes very slow before it blocked...
could you help me?
Aurora
modified 23-Dec-11 13:02pm.
|
|
|
|
|
Hi otom,
Firstly, thanks for this code sample, it is very clean and mostly works perfectly.
However, I think I have seen the same problem that is reported here, namely, the ::List() operation blocks forever.
I was wondering if you have seen this, or whether you have made any changes that might fix this in V2.0?
Thank you again,
Ben
|
|
|
|
|
I got the FTPClient Code compiled for Linux, but first it didn't work. The problem was,
that for some select() calls in the code, the first parameter nfds was set to 0. This doesn't
matter under Windows, because this parameter is ignored.
Under Linux, the first parameter in select() must be set to the highest file descriptor + 1
Regards,
KH
|
|
|
|
|
Hi,
I'm testing your demo project, but when I run it, I don't obtain the logging response. Using a break point in function
void CFTPProtocolOutput::OnResponse(const tstring& strResponse)
on first line, the execution of the application is not stopped. Of course response string is not logging.
Can you help me to understand why this event occurred?
10x
===============================================================
Ok,
I found the solution to what was previously reported.
In the example you have made
void CFTPProtocolOutput: OnResponse (const & tstring strResponse)
but evidently, after this, you have modified the parent object
and then you must override
void CFTPProtocolOutput: OnResponse (const CReply & reply)
and working properly.
Because I have written, I must point out that in the function
void CFTPProtocolOutput: OnSendCommand (const tstring & strCommand)
you have entered the instruction
if (strCommand.length ()> 4 & & strCommand.substr (5) == _T ("PASS"))
but, at least with VS2008, this does not work. I corrected it in
if (strCommand.length ()> 4 & & strCommand.substr (0, 5) == _T ("PASS"))
and it's work fine.
Excellent work,
10x
Sandro
modified 20-Dec-11 8:48am.
|
|
|
|
|
Hi,
I'll want to know what's kind of licence is applied to this project. Can I use it for free in commercial and/or open source code?
10x
Sandro
Sandro
|
|
|
|
|
yes, you can use it in commercial applications; i have set the license to "The Code Project Open License (CPOL)"
|
|
|
|
|
Hello Sir,
I am using your source code in my project & Its working fine. But I have one problem I could not find the size of file which is on server(Linux). I am getting following message.
550 SIZE not allowed in ASCII mode
Could please provide solution to calculate size of file.
Regards,
Savio
|
|
|
|
|
it seems that the server doesn't understand the SIZE command; you have to check the server; maybe there is another command that you can send; in windows you can use the Microsoft command line tool "ftp.exe"; first you have to connect to the FTP server and then you must type "remotehelp"; the server should show you the commands which are supported
|
|
|
|
|
Hi,
Thanks for the project. It works well, and the code is great and understandable.
I have a requirement to write a Data Stream instead of File stream over a FTP session. Would that be possible by modifying this code? This is my requirement,
1. Establish a ftp session
2. Create the target file on the ftp session.
3. Send a data send a data stream over the session.
4. Once data stream is done, close the session.
I could not visualize what I need to modify to achieve this. Is this achievable, if yes can you tell me your views what I should do to achieve this?
Siva
|
|
|
|
|
I am using your source code for FTP communication. But when I try to connect with secure FTP I could not upload data on secure FTP. So how do I communicate with secure FTP?
Thanks & Regards,
Savio
|
|
|
|
|
SFTP is NOT RELATED to FTP. This means that you can't use my classes for SFTP communication. I don't know if there exists free classes for doing SFTP stuff.
|
|
|
|
|
Good job, Thanks!
I have take this project to use in VC7 for a MFC App.
I find that you must add the WSAStartup to initial the socket.
But why your demo project don't need the WSAStartup.
|
|
|
|
|
dear otom
when using CFTPClient::DownloadFile,I set strLocalFile value with chinese word, such as _T("D:\\下载文件夹\\down.txt").
the ConvertToString(strFileName).c_str() in
m_pFile = fopen(CCnv::ConvertToString(strFileName).c_str(), <br />
CCnv::ConvertToString(strMode).c_str()); get wrong. not “D:\\下载文件夹\\down.txt”.
i change the code in definements.h, then it goes right
static std::string& ConvertToString(const tstring& strIn, std::string& strOut)
{
#ifdef _UNICODE
if( strIn.size() == 0 )
{
strOut.clear();
}
else
{
setlocale(LC_ALL, ".936");
int nSizeRequired = wcstombs(NULL, strIn.c_str(), 0);
strOut.resize(nSizeRequired);
wcstombs(&*strOut.begin(), strIn.c_str(), nSizeRequired);
//strOut.resize(strIn.size());
//wcstombs(&*strOut.begin(), strIn.c_str(), strOut.size());
}
#else
strOut = strIn;
#endif
return strOut;
}
but i think the better way to fix this problem, i should fix CFile, make it support unicode,such as using
_tfopen instead of fopen. Maybe you have a better way, please tell me
|
|
|
|
|
Hello.
First of all, it's really a good ftp library, but, unfortunately, I have one problem with it.
Abort command takes a lot of time. I did some debugging, and noticed, that after "ABOR" command is sent
GetResponse(Reply) - at line 1002 in FTPClient.cpp takes a lot of time.
I tried provided example with Progress Dialog with two different ftp servers.
In both cases, when I press Abort button, Progress Dialog disappears and everything is disabled(I can't even move main window)
for a noticeable amount of time(less than minute, but still).
Any help would be highly appreciated!
P.S Sorry for my english
|
|
|
|
|