|
Dear all,
I will use the ftp-client without MFC, but only in a Console. What must I change for use the source code in a console-application?
Can you help me?
your sincerely
|
|
|
|
|
In the next release (within the next month) there will be an example without mfc and console output.
|
|
|
|
|
When would this next release be released?
Best regards,
Merijn
|
|
|
|
|
Next release is within the next week.
|
|
|
|
|
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.
|
|
|
|