|
Great! Thank You very much!
Merijn
|
|
|
|
|
No matter how I try, all files I download are always downloaded in ASCII Mode. But I _must_ use the Binary Mode.
What options or parameters do I have to set, to get 'FTPClient.DownloadFile()' to work in Binary Mode?
Thanks for help.
Ralf
|
|
|
|
|
After reading "DLLs are Simple! Part 3" by Mahmood Komeily
I created a DLL project in his light including some ftp opreating functions
and its test project
I compiled, traced and found:
An exceptional messagebox occured at line 349 in FtpClient file, saying like: Unhandled exception in msvcr71d.dll, writing at 0x8d087d8b happens with accessing conflict.
At last it interrupted at line 263 in file memcpy.asm( mov [edi],al;U - write second byte to destination)
Can you help me with this problem? Thanks in advance!
-- modified at 5:57 Wednesday 14th September, 2005
|
|
|
|
|
After using Mfc Extension DLL my project can work well now.
Thanks
|
|
|
|
|
today i tried to compile your little example using dev-c++, because it's the only environment available at work.
It seems nearly impossible due to hundrets of compiling errors.
i will try compiling using some other compilers at home, but for now i really need a solution for dev-c++.
did you come accross this problem already and know a solution?
regards,
georgeblunt
|
|
|
|
|
You are right, there are a lot of warnings and errors in dev-c++. Currently I am working on a new release of the project. There is a lot of stuff (like CException) which is Microsoft specific. In the new version this parts will be replaced with standard conform code. I will try to run the new classes also in dev-c++ and maybe under linux. The new version will be released this year (it will take some time because I have no experience with dev-c++ and other platforms, so be patient).
|
|
|
|
|
Thank you very much for your answer. I appreciate your work and care an am looking forward to the new version. ^^
|
|
|
|
|
In DownloadFile_C you call fopen immediately followed by a fseek - if fopen fails you will get a crash in fseek.
Right after the fseek you check if the fopen failed and if so returns, so the solution is quite easy: move the fseek to after the check.
Thanks for a nice component!
|
|
|
|
|
I was happy,when found this component,but all the time using it, I think:
WHY SO SLOW ?
I create small application for Ethernet network 100Mb and big delays make me crazy. So I reseach all function on time interval and find strange code
string Sleep(50) in GetSingleResponseLine function.May be author decide to play a mean trick with developes which use this component.;P
So can delete this line string.
Enjoy.
|
|
|
|
|
I got this problem when I want to delete the file after upload it, the file was still opened and can not be deleted.
To fix this bug, add code as below to FtpClient.cpp line 811 --
fclose(pFile);
|
|
|
|
|
Beforehand apologize for my english
Old code:
// set passive mode
// the ftp server opens a port and tell us the socket (ip address + port)
// this socket is used for opening the data connection
if( Passive(strRemoteHost, uiServerSock)!=FTP_OK )
return false;
// if resuming is activated then set offset
if( m_fResumeIfPossible &&
(crDatachannelCmd==CDatachannelCmd::cmdSTOR || crDatachannelCmd==CDatachannelCmd::cmdRETR || crDatachannelCmd==CDatachannelCmd::cmdAPPE ) &&
(dwByteOffset!=0 && Restart(dwByteOffset)!=FTP_OK) )
return false;
// send FTP command RETR/STOR/NLST/LIST to the server
if( !SendCommand(GetCmdString(crDatachannelCmd, strPath)) )
return false;
--->>IN THIS PLACE CLIENT WAIT FOR SERVER RESPONSE,BUT ITS
--->>IMPOSSIBLE,BECAUSE AT FIRST CLIENT MUST ESTABLISH DATA CONNECTION TO
--->>SERVER
// get response from server
int iFirstDigitOfReplyCode = -1;
if( !GetResponse(iFirstDigitOfReplyCode) || iFirstDigitOfReplyCode!=1 )
return false;
// establish connection
CSockAddr sockAddrTemp;
try
{
sckDataConnection.Create(SOCK_STREAM);
CSockAddr csaAddress(strRemoteHost.c_str(), static_cast<ushort>(uiServerSock));
sckDataConnection.Connect(csaAddress);
}
catch(CBlockingSocketException* pException)
{
ReportError(pException->GetErrorMessage(), __FILE__, __LINE__);
pException->Delete();
sckDataConnection.Cleanup();
return false;
}
return true;
FIXED:
// set passive mode
// the ftp server opens a port and tell us the socket (ip address + port)
// this socket is used for opening the data connection
if( Passive(strRemoteHost, uiServerSock)!=FTP_OK )
return false;
// establish connection
-->> I MOVE CODE FROM END OF FUNCTION INTO THIS
-->> PLACE AND ALL WORK GREAT
CSockAddr sockAddrTemp;
try
{
sckDataConnection.Create(SOCK_STREAM);
CSockAddr csaAddress(strRemoteHost.c_str(), static_cast<ushort>(uiServerSock));
sckDataConnection.Connect(csaAddress);
}
catch(CBlockingSocketException* pException)
{
ReportError(pException->GetErrorMessage(), __FILE__, __LINE__);
pException->Delete();
sckDataConnection.Cleanup();
return false;
}
// if resuming is activated then set offset
if( m_fResumeIfPossible &&
(crDatachannelCmd==CDatachannelCmd::cmdSTOR || crDatachannelCmd==CDatachannelCmd::cmdRETR || crDatachannelCmd==CDatachannelCmd::cmdAPPE ) &&
(dwByteOffset!=0 && Restart(dwByteOffset)!=FTP_OK) )
return false;
// send FTP command RETR/STOR/NLST/LIST to the server
if( !SendCommand(GetCmdString(crDatachannelCmd, strPath)) )
return false;
// get response from server
int iFirstDigitOfReplyCode = -1;
if( !GetResponse(iFirstDigitOfReplyCode) || iFirstDigitOfReplyCode!=1 )
return false;
|
|
|
|
|
Very important correction! Should be included in a new version!
Regards,
Adam
|
|
|
|
|
Can I use this class in asynchronous mode, i.e., while I upload a file, before the end of the upload, can I see the number of bytes that was sended?
I it is possible, how can I do it?
Thanks
Rodrigo
|
|
|
|
|
Please, can you also make an example in vc6? In my vc6 versions i have many compile errors, but i dont think why.
best regards
NielsR
|
|
|
|
|
Problems lies in: VC6 compiler does not support sdt::auto_ptr::Reset(...) !
For example, in file FtpClient.cpp line 843:
m_apCurrentRepresentation.reset(...);
you can just replace it with following code:
m_apCurrentRepresentation.release();
m_apCurrentRepresentation = std::auto_ptr<crepresentation>(new CRepresentation(CType::ASCII()));
|
|
|
|
|
No, that is not right. You should use something like this:
delete m_apCurrentRepresentation.release();
m_apCurrentRepresentation = std::auto_ptr<crepresentation>(new CRepresentation(CType::ASCII()));
Regards,
Adam
|
|
|
|
|
That didn't work for me either. After a ton of trial and error I came up with this:
delete m_apCurrentRepresentation.release();
std::auto_ptr<CRepresentation> temp_crep( new CRepresentation(CType::ASCII()) );
m_apCurrentRepresentation = temp_crep;
You will also need to comment out the List and NameList functions (hope you don't need them) to get it to compile in vc6. ...And the following line
std::copy(vBuffer.begin(), vBuffer.begin()+lReceivedBytes, std::back_inserter(m_vBuffer));
|
|
|
|
|
FTP-Server response no newline. Only statuscode 250 strTemp.length() is 3
Filezillaserver do this often.
after
int iCRLF=strTemp.find('\n');
iCRLF is -1; // \n notfound.
Your code delete the string with
strTemp.erase(0, iCRLF+1);
but iCRLF is -1 an
strTemp.erase(0, -1+1);
don`t delete any chars in the string.
Now
while( strTemp.length() )
never end
Bugfix
int iCRLF=strTemp.find('\n');
if( iCRLF>-1 )
{
m_qResponseBuffer.push(strTemp.substr(0, iCRLF+1));
strTemp.erase(0, iCRLF+1);
}
else
{
m_qResponseBuffer.push(strTemp);
strTemp.erase(0, 1);
}
strTemp.erase(0, -1+1);
|
|
|
|
|
It's not a problem in parsing strTemp. It's a problem with receiving. I think that any FTP server should end every command with \n, but when a server has limited bandwith a packet can be cutted off into two or more pieces. Your:
strTemp.erase(0, 1);
will avoid the infinite loop but it passes an unfinished command to the queue and the client parses that command in a wrong way.
That's why I suggest slightly different bugfix:
if( m_qResponseBuffer.empty() )
{
// internal buffer is empty ==> get response from ftp-server
int iNum=0;
tstring strTemp;
bool bContinue = true;
while (bContinue)
{
do
{
int size = m_vBuffer.size();
iNum=m_sckControlConnection.Receive(&(*m_vBuffer.begin()), m_vBuffer.size()-1, mc_uiTimeout);
Sleep(50);
m_vBuffer[iNum]=_T('\0');
strTemp+=&(*m_vBuffer.begin());
} while( iNum==static_cast<int>(m_vBuffer.size())-1 );
// each line in response is a separate entry in the internal buffer
while( strTemp.length() )
{
int iCRLF=strTemp.find('\n');
if( iCRLF>-1 )
{
m_qResponseBuffer.push(strTemp.substr(0, iCRLF+1));
strTemp.erase(0, iCRLF+1);
bContinue = false;
}
else
{
bContinue = true;
break;
}
}
}
if( m_qResponseBuffer.empty() )
return false;
}
In my code the Receive is invoked in a loop until it reaches the new-line.
Let me know if it helped you.
Regards,
Adam
|
|
|
|
|
Please, check UNICODE types mappings in your code, these seem broken in many places.
Vsevolod Gromov
|
|
|
|
|
You are right. There are a few parts in the code that use std:string instead of tstring. In the next version it will be fixed.
|
|
|
|
|
Following previuos message - regarding CBlockingSocket, AFAIK, send & recieve methods should accept byte buffers (i.e. char*), as long as it's not UNICODE, LPCTSTR & LPTSTR will do, but things will (or, at least, there is high probability that they may) break here if UNICODE is set, I believe.
Also, it would be nice to get rid of MFC dependency completely, dropping CObject & CException bases.
My dream is to left STL out too, its streams & strings & etc are handy, but code bloat, especially after stream include, dumb string implementation...
Anyway, there's a lot of work to do, please, don't leave this nifty lightweight class unattended.
PS. GetErrorDescription impl. is duplicated, maybe, it's good idea to put it into separate "utilities" unit?
Vsevolod Gromov
|
|
|
|
|
Yeah, you are right. The packets should be sent in ASCII.
I've recently revised all of the code and prepare a working version that compiles in Unicode. Let me know if you're interested, I can send it to anyone.
Regards,
Adam
|
|
|
|
|
Adam, I think that many people are interested in getting your class' updates, so it'd be useful to check-in files attached to your article, instead of explicitly sending them to correspondents.
Vsevolod Gromov
|
|
|
|