http://www.codeproject.com/KB/IP/SocketFileTransfer.aspx?artkw=socket%20send%20a%20file 我不清楚这一行: //首先获取文件的大小
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 addr的字节指针,但+ sizeof(dataLength) - cbLeftToReceive
是什么意思?
我不认为文件那么小:4个字节,只是onc接收它们如何接收dataLength和数据?它首先发送dataLength而后发送数据吗?
答案 0 :(得分:3)
喔。有趣的数组算术。这个想法是从最后开始算,所以当你到达终点时,你知道你已经完成了。分段:
1.找到dataLength (BYTE*)(&dataLength)
的地址
2.跳到dataLength + sizeof(dataLength)
的结尾
3.按我们期望接收的字节数- cbLeftToReceive
进行备份
这是我们编写从网络获得的字节的地方。
当我们从网络中获取字节时,我们减少cbLeftToReceive(cbLeftToReceive -= cbBytesRet;
)并继续尝试接收字节,直到完成为止。因此,每次循环时,bp指向我们需要写入下一个字节的位置,我们接收()。
编辑:
现在我们知道我们将获得多少字节,如何在不填充所有数据量的RAM的情况下接收它们?我们得到一个缓冲区,重复填充它,并在缓冲区空闲时将该缓冲区刷新到磁盘。当剩下大量数据(超过缓冲区)时,我们尝试接收()一个填充缓冲区。如果没有完整的缓冲区,我们只会请求文件的末尾。
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 );
一般建议: 练习阅读代码是很好的,因为你不必过多关注错误处理和异常处理代码。通常情况下,更容易理解。
答案 1 :(得分:0)
他/她意味着他在缓冲区的开头放置了int的大小,文件的大小将被放置(稍后将从套接字中读取)