2010-10-23 66 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的大小(它會從插座後讀)