2010-10-23 81 views
1

http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx?artkw=socket%20send%20a%20file 我并不清楚地了解这一行: //获取文件的大小第一指针在C++ - 需要解释它是如何工作

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_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); 

我想知道如何得到它得到的文件大小到dataLength :)

此行:BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;这是正确的,bp是dataLength地址的一个字节指针,但+ sizeof(dataLength) - cbLeftToReceive是什么意思?

我不认为该文件是那么小:4个字节,只是onc接收他们如何接收dataLength和数据?它先发送dataLength,然后发送数据吗?

+0

你引用的代码中最令人担忧的部分是这个发送者和接收者都假定这个长度可以适合int。 (我仍然记得4GB的文件是无法想象的巨大的,现在我不认为它是这样的。) – 2010-10-23 08:43:33

回答

3

哦。有趣的数组算术。这个想法是从最后算起,这样当你到达最后,你就知道你已经完成了。在片:
1.查找数据长度的(BYTE*)(&dataLength)
2.我们希望接收的字节数跳到DATALENGTH + sizeof(dataLength)年底
3.备份地址- cbLeftToReceive
这是我们写字节我们从网络中获得。当我们从网络中获取字节时,我们减少cbLeftToReceive(cbLeftToReceive -= cbBytesRet;),并继续尝试接收字节,直到完成为止。所以每次通过循环时,bp指向我们需要写入下一个字节的地方,我们接收()。

编辑:

所以现在我们知道我们要多少字节就搞定了,怎么我们收到他们没有可能填补所有的RAM与数据的帅哥?我们得到一个缓冲区,重复填充缓冲区,并在缓冲区不是空的时候将缓冲区刷新到磁盘。当仍有大量数据(超过一个缓冲区)留下来接收时,我们尝试Receive()一个填充缓冲区。当缓冲区不足时,我们只需要到文件结尾。

 
    iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? 
         cbLeftToReceive : RECV_BUFFER_SIZE ; 
    iiRecd = sockClient.Receive(recdData, iiGet); 

我们捕捉并处理错误。如果没有错误,请写出我们得到的很多字节,并减少我们希望得到的字节数。

 
    destFile.Write(recdData, iiRecd); // Write it 
    cbLeftToReceive -= iiRecd; 

如果我们还没有完成接收字节,返回顶部继续前进。

 
    while (cbLeftToReceive > 0); 

一般建议: 这是很好的练习阅读的代码,你不付出太多注意错误处理和异常处理代码。通常剩下的东西更容易理解。

+0

感谢Eric给出了非常明确的答案,但是数据和dataLength如何,你能为我解释吗? – nXqd 2010-10-23 09:05:45

+0

来自你的惊人答案,非常感谢:) – nXqd 2010-10-23 14:59:17

0

他/她的意思,他留出在缓冲区中,该文件的大小,放入开始为int的大小(它会从插座后读)