|
To send across the file name, you could prepend the file's data with the file's name in a header struct, which appears to be what you were starting to do. Your receive code would have to be more intelligent in this case... instead of just dumping whatever it receives over the socket into a file, you'd have to look for the header first and then continue on.
It's important that your receive code only pulls in the header initially, and that it doesn't spill over into the file data. That's what
nRead = pSocket->Receive( byBuffer + nPos, sizeof( FileHeader ) - nPos );
nPos += nRead;
</code>
is doing in the following pseudo code. It will only read at a maximum sizeof( FileHeader ) bytes. You can't assume that you'll get all of those bytes in one pass, however, which is why you still have to put it in a do..while.
typedef struct
{
char szFileName[_MAX_PATH];
} FILE_HEADER, *LPFILE_HEADER;
send_code()
{
... Get the file name
#define BUFFER_SIZE 4096
long nRead = 0;
BYTE byBuffer[BUFFER_SIZE];
FILE_HEADER FileHeader;
strcpy( FileHeader.szFileName, myFile.GetFileName() );
cSocket->Send( dynamic_cast< LPVOID >( &FileHeader ), sizeof( FileHeader ));
do
{
nRead = myFile.Read( byBuffer, BUFFER_SIZE );
cSocket->Send( byBuffer, nRead );
} while( nRead > 0 );
... clean up
}
receive_code()
{
long nRead = 0;
long nPos = 0;
BYTE byBuffer[BUFFER_SIZE];
FILE_HEADER FileHeader;
do
{
nRead = pSocket->Receive( byBuffer + nPos, sizeof( FileHeader ) - nPos );
nPos += nRead;
} while( (nPos < sizeof( FileHeader )) && (nRead > 0) );
if( nPos != sizeof( FileHeader ) )
{
return;
}
... create file with FileHeader.szFileName
do
{
nRead = pSocket->Receive( byBuffer, BUFFER_SIZE );
destFile.write( byBuffer, nRead );
} while( nRead > 0 );
}
</code>
Ty
"The significant problems we face cannot be solved at the same level of thinking we were at when we created them." -Albert Einstein
|
|
|
|
|
why not use archives to simplify things?
Sending code would be
<br />
CSocket cSocket;<br />
cSocket.Create();<br />
cSocket.Connect((LPCTSTR(m_strServerIP)),m_iFtPort);<br />
<br />
CSocketFile sf(&cSocket);<br />
CArchive ar(&sf, CArchive::store);<br />
<br />
<br />
strPath = m_ldFile.GetPathName();<br />
CFile myFile(strPath,<br />
CFile::modeRead | CFile::typeBinary); <br />
<br />
DWORD length = myFile.GetLength();<br />
char *data = new char[length];<br />
myFile.Read(data, length);<br />
<br />
ar << myFile.GetFileName();<br />
ar << length;<br />
ar.Write(data, length);<br />
<br />
delete[] data;<br />
myFile.Close(); <br />
and on the receiving side, just the reverse process
<br />
CSocketFile sf(pSocket);<br />
CArchive ar(&sf, CArchive::load);<br />
<br />
CString filename;<br />
ar >> filename;<br />
CFile m_destFile(filename,<br />
CFile::modeCreate | CFile::modeWrite | CFile::typeBinary);<br />
<br />
DWORD length;<br />
char *data;<br />
<br />
ar >> length;<br />
data = new char[length];<br />
ar.Read(data, length);<br />
<br />
m_destFile.Write(data, length);<br />
m_destFile.Flush();<br />
<br />
delete[] data;<br />
m_destFile.Close();<br />
I don't know about the do..while for the Read/Write though, this code is working fine for me
Bilal Naveed
|
|
|
|
|
Thanks to both of you for replying so fast and providing source code!! While I was waiting for a post I implemented CreatFile and TransmitFile, this worked but I haven't sent across the filename.. I think I will play around with the code you 2 provided to see what method I like best.
Thanks alot!!
Rob
|
|
|
|
|
I am going to use the code you provided me. Thanks again!! one last question do you know of a way to see the progress of the ar.Write and ar.Read.. When sending files like this across the internet the process can take some time, it would be nice to see progress if possible.
Thanks again for all your help!
Rob
|
|
|
|
|
Well I couldn't find any... a crude workaround could be to use ar.Write in a loop, sending across fixed-sized chunks of your file and updating progress accordingly.
Bilal
|
|
|
|
|
Hi,
How I can convert UTF-8 to Unicode strings on Pocket PC 2000? I tried
MultiByteToWideChar, but it only works with Pocket PC 2002, in Pocket PC
2000 it returns an empty string with GetLastError "Invalid Parameter",
probably because of non suport for this char-set on Pocket PC 2000.
I also tried TnefConvertToUnicode in Tnefapi.h, but my installed
hardware does not support this function (HP Jornada and Compaq iPaqs), and I
tried to build my own conversion function with some code found on the
internet, but it is too slow.
Anybody knows how to convert this kind of string? (any code sample or
open source program that does this will help)
TIA
Guilherme Magalhaes - guilherme@flag.com.br
MCP - MCSD
|
|
|
|
|
Don't need if this will help you, but ::MultiByteToWideChar() is just a wrapper of mbstowcs() (implemented in the C-runtime, thus cross-platform).
MS quote (http://www.microsoft.com/ddk) : As of September 30, 2002, the Microsoft® Windows® 2000 DDK, the Microsoft Windows 98 DDK, and the Microsoft Windows NT® 4.0 DDK will no longer be available for purchase or download on this site.
|
|
|
|
|
Hi,
I've created a user-interface thread using:
m_pDevice = (CDevice*)AfxBeginThread(RUNTIME_CLASS(CDevice),
THREAD_PRIORITY_NORMAL,
0, // stack size
CREATE_SUSPENDED);
Now, the probles is that when the aplication end a get a memory leak ( the m_bAutoDelete of CDevice which is inherited from base class CWinThread is set TRUE by default ).
I've also tryed m_pDevice->Delete() but no succes... I always get :
Detected memory leaks!
Dumping objects ->
{71} client block at 0x00AE64B8, subtype c0, 92 bytes long.
a CDevice object at $00AE64B8, 92 bytes long
Object dump complete.
Thanx
|
|
|
|
|
How do you know if the thread has completed, when your applications ends? The fact that it leaks and that your Delete() call doesn't stop the leak makes me think that the thread is still executing when you are trying to end your application. Put in a WaitForSingleObject() before exiting the application to ensure that the thread completes.
Chris
|
|
|
|
|
Hi world...
I've got some error compilation when I want to catch the address of a method inside his class...
My code is:
int BsCard::InitInterrupt() const
{
void (BsCard:: *intHdl)(HANDLE hCHA_DIG, INT_RESULT* pintResult) = this->InterruptHandler;
if (!IntEnable(m_hCard, intHdl)) {
printf("Enabling Interrupt failed\n");
return ERR_INITINT;
}
return 0;
}
My method who I want to pass her address is:
void BsCard::InterruptHandler(HANDLE hCHA_DIG, INT_RESULT* pintResult)
{
}
My error compilation is:
C:\My Projects VC++\Generic DLL Architecture\MyDLL\RedCode\BsCard.cpp(267) : error C2664: 'IntEnable' : cannot convert parameter 2 from 'void (__thiscall BsCard::*)(struct STRUCT *,INT_RESULT *
)' to 'void (__cdecl *)(struct STRUCT *,INT_RESULT *)'
There is no context in which this conversion is possible
The problems seems to come from the (__cdecl *) ... But I'm not sur.
Thanks for any clues...
Hello World!!!
from Raphaël
|
|
|
|
|
void (__stdcall BsCard:: *intHdl)(HANDLE hCHA_DIG, INT_RESULT* pintResult)
MS quote (http://www.microsoft.com/ddk) : As of September 30, 2002, the Microsoft® Windows® 2000 DDK, the Microsoft Windows 98 DDK, and the Microsoft Windows NT® 4.0 DDK will no longer be available for purchase or download on this site.
|
|
|
|
|
Make the method static . This has obvious limitations: if you need to circumvent them, check Mike Dunn's VC++ FAQ[^], §6.1.
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Here's some example code that can at least point you in the right direction:
class BsCard
{
public:
typedef void (BsCard::*FuncPtr)(HANDLE hCHA_DIG, INT_RESULT* pintResult);
void InterruptHandler(HANDLE hCHA_DIG, INT_RESULT* pintResult);
bool IntEnable(int, FuncPtr){return true;};
int InitInterrupt1();
int InitInterrupt2();
int m_hCard;
};
int BsCard::InitInterrupt1()
{
void (BsCard::*intHdl)(HANDLE hCHA_DIG, INT_RESULT* pintResult) = this->InterruptHandler;
if (!IntEnable(m_hCard, intHdl)) {
printf("Enabling Interrupt failed\n");
return ERR_INITINT; // Enabling Interrupt failed
}
return 0;
}
int BsCard::InitInterrupt2()
{
FuncPtr intHdl = this->InterruptHandler;
if (!IntEnable(m_hCard, intHdl)) {
printf("Enabling Interrupt failed\n");
return ERR_INITINT; // Enabling Interrupt failed
}
return 0;
}
void BsCard::InterruptHandler(HANDLE hCHA_DIG, INT_RESULT* pintResult)
{
}
Using above method, it's going to be hard to keep your InitInterrupt as a const type.
I recommend you change it to a none-constant function.
|
|
|
|
|
I got a string represented by std::string. I want to remove all the leading and trailing spaces from it and and not the spaces in the middle. How ????
|
|
|
|
|
find_first_of() and find_last_of() .
|
|
|
|
|
Look here[^].
Joaquín M López Muñoz
Telefónica, Investigación y Desarrollo
|
|
|
|
|
Example functions:
void TrimLeft(std::string &Src, char c = ' ')
{
while(Src.size() && Src[0] == c) Src.erase(0,1);
}
void TrimRight(std::string &Src, char c = ' ')
{
while(Src.size() && Src[Src.size()-1] == c) Src.erase(Src.size()-1,1);
}
Example usuage:
int main(int argc, char* argv[])
{
std::string Data1 = " Hello World";
std::string Data2 = "Hello World ";
std::string Data3 = " Hello World ";
std::string Data4 = " ";
std::string Data5 = "";
TrimLeft(Data1);
TrimLeft(Data2);
TrimLeft(Data3);
TrimLeft(Data4);
TrimLeft(Data5);
TrimRight(Data1);
TrimRight(Data2);
TrimRight(Data3);
TrimRight(Data4);
TrimRight(Data5);
return 0;
}
|
|
|
|
|
Hi..
Currently i'm develop one application on desktop...There are two version
1st version are written in VC++ and another version in VB 6.0...but the speed between this two application is within 4 - 9 second...Actually this application do is read a data from the SmartCard....
:_Rocket_:
|
|
|
|
|
I've created a 3 Pane Splitter using two splitter windows like a T on its side:-
|-
I have an Control in the bottom right hand side,
When I move the column splitter the Scrollbars disapear for the control, and only reapear if i move the row (-) splitter bar,
What function to i need to call after an OnSize to ENSURE that the entire client area is drawn?
Asim Hussain
e: asim@jawache.net
w: www.jawache.net
|
|
|
|
|
Dear all,
Correct me if I'm wrong, is memory leak due to not using delete after a new ?
Is there a program to check my program for memory leak?
Thanks
Chun Te, Ewe
|
|
|
|
|
Chun Te, Ewe wrote:
Correct me if I'm wrong, is memory leak due to not using delete after a new?
Yes. Or using delete instead of delete[] for an array made with new[]
Chun Te, Ewe wrote:
Is there a program to check my program for memory leak?
'BoundsChecker' or 'Purify' spring to my mind. Both are big money, but very good.
|
|
|
|
|
jhwurmbach wrote:
'BoundsChecker' or 'Purify' spring to my mind. Both are big money, but very good.
Are there any freewares around?
|
|
|
|
|
Not really.... the tools available are really for checking whether you are going past array bounds or accessing memory that hasn't been allocated. VC++ tells you when you have a memory leak and thats about as much help as your going to get anywhere.
There are a number of good articles here about how to trace your memory leaks better, look in 'Programming Tips'
Asim Hussain
e: asim@jawache.net
w: www.jawache.net
|
|
|
|
|
Just being obnoxious: if I'm not mistaking the 'delete[]'-syntax is no longer needed when trying to delete an array. Following code does exactly the same thing twice:
void main() {
char* s = new char[10];
delete s;
char* p = new char[10];
delete []p;
}
|
|
|
|
|