Pointer in C++ - Need explanation how it works
http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx?artkw=socket%20send%20a%20file I don't clearly understand this line : // get the file's size first
cbLeftToReceive = sizeof( dataLength );
do
{
BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );
// test for errors and get out if they occurred
if ( cbBytesRet == SOCKET开发者_StackOverflow_ERROR || cbBytesRet == 0 )
{
int iErr = ::GetLastError();
TRACE( "GetFileFromRemoteSite returned
a socket error while getting file length\n"
"\tNumber of Bytes received (zero means connection was closed) = %d\n"
"\tGetLastError = %d\n", cbBytesRet, iErr );
/* you should handle the error here */
bRet = FALSE;
goto PreReturnCleanup;
}
// good data was retrieved, so accumulate
// it with already-received data
cbLeftToReceive -= cbBytesRet;
}
while ( cbLeftToReceive > 0 );
I want to know how get it get size of the file to dataLength :)
This line : BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
does it right that bp is a byte pointer of dataLength addr but what + sizeof(dataLength) - cbLeftToReceive
mean ?
I don't think the file is that small : 4 bytes, just onc Receive how can they receive dataLength and data ? Does it send dataLength first and data after ?
Oh. The funny array arithmetic. The idea is to count from the end, so that when you reach the end you know you're done. In pieces:
1. Find the address of dataLength (BYTE*)(&dataLength)
2. Skip to the end of dataLength + sizeof(dataLength)
3. Back up by the number of bytes we expect to receive - cbLeftToReceive
This is where we are writing the bytes we get from the network.
As we get bytes from the network, we reduce cbLeftToReceive (cbLeftToReceive -= cbBytesRet;
) and continue trying to receive bytes until we are done. So every time through the loop, bp points to where we need to write the next bytes we Receive().
EDIT:
So now that we know how many bytes we're going to get, how to we receive them without potentially filling all of RAM with hunks of the data? We get a buffer, repeatedly fill it, and flush that buffer to disk whenever it's not empty. When there's still a lot of data (more than a buffer) left to receive, we try to Receive() a fill buffer. When there's less than a full buffer to go, we only request to the end of the file.
iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? cbLeftToReceive : RECV_BUFFER_SIZE ; iiRecd = sockClient.Receive( recdData, iiGet );
The we catch and handle errors. If there was no error, write however many bytes we got and reduce the number of bytes we expect to receive by the number we got.
destFile.Write( recdData, iiRecd); // Write it cbLeftToReceive -= iiRecd;
If we're still not done receiving bytes, go back to the top and keep going.
while ( cbLeftToReceive > 0 );
General advice: It's good to practice reading code where you don't pay too much attention to the error handling and exception handling code. Typically what's left is much easier to understand.
He/She means that he sets aside the size of int in the start of the buffer, where the size of the file will be placed (it will be later read from the socket)
精彩评论