Указатель в C ++ - нужно объяснение, как это работает - PullRequest
1 голос
/ 23 октября 2010

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 является байтовым указателем addLength addr, но что означает + sizeof(dataLength) - cbLeftToReceive? 1010 *

Не думаю, что файл настолько мал: 4 байта, только onc Получите, как они могут получить dataLength и данные?Отправляет ли сначала dataLength, а затем данные?

Ответы [ 2 ]

3 голосов
/ 23 октября 2010

О.Смешная арифметика массива.Идея состоит в том, чтобы считать с конца, чтобы, когда вы дойдете до конца, вы знали, что все готово.В кусочках:
1. Найдите адрес dataLength (BYTE*)(&dataLength)
2. Перейдите к концу dataLength + sizeof(dataLength)
3. Вернитесь на количество байтов, которое мы ожидаем получить - cbLeftToReceive
Здесь мы записываем байты, которые мы получаем из сети.

Получая байты из сети, мы уменьшаем cbLeftToReceive (cbLeftToReceive -= cbBytesRet;) и продолжаем пытаться получать байты до тех пор, пока не закончим.Таким образом, каждый раз в цикле bp указывает, куда нам нужно записать следующие байты, которые мы получаем ().

РЕДАКТИРОВАТЬ:

Итак, теперь мы знаем, сколько байтов мы собираемсяполучить, как мы можем получить их, не заполняя все ОЗУ кусками данных?Мы получаем буфер, повторно заполняем его и сбрасываем этот буфер на диск всякий раз, когда он не пустой.Когда осталось еще много данных (больше, чем буфер) для получения, мы пытаемся получить () заполнить буфер.Когда осталось меньше полного буфера, мы запрашиваем только конец файла.

  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 голосов
/ 23 октября 2010

Он / она означает, что он устанавливает размер int в начале буфера, куда будет помещен размер файла (он будет позже считан из сокета)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...