Что пишет MSDN:Описание нотификации INTERNET_STATUS_RESPONSE_RECEIVED гласит:
Successfully received a response from the server. The lpvStatusInformation parameter points to a DWORD value that contains the number of bytes received.
Как оно на самом делеВо-первых, когда это сообщение приходит в первый раз, в «number of bytes received» содержится полное число принятых байтов. В случае HTTP-запроса в них входят и заголовки. Но прочитать эти
все принятые данные с помощью
InternetReadFile у вас не получится, потому что о
вас позаботились, и сделали так, что InternetReadFile читает только тело HTTP-ответа. Это значит, что чтобы хоть как-то прочитать тело ответа, вам нужно самим (к черту такая забота?) отследить момент, когда придут все заголовки, определить их длину и отнять от числа, которое вам сообщили с INTERNET_STATUS_RESPONSE_RECEIVED, чтобы узнать, сколько действительно байтов вы можете прочитать с помощью
InternetReadFile.
Но это ещё не всё.
Во-вторых, INTERNET_STATUS_RESPONSE_RECEIVED сообщает не о том (кроме первого раза), сколько байтов
действительно принято, а о том, сколько байтов из тех, что вы просили, приятно. Под «сколько вы просили» понимается попытка прочитать данные из буфера, котороых в буфере нет!
Допустим, вам сначала пришло 200 байт. Из них 150 — заголовки, 50 — тело сообщения. Вы вызываете InternetReadFile, чтобы прочитать эти 50 байт себе, прочитываете. Дальше вы ждёте «события» INTERNET_STATUS_RESPONSE_RECEIVED, чтобы узнать, когда придёт следующая порция, и прочитать её.
Так? Ждёте? Ждите-ждите. Новое событие INTERNET_STATUS_RESPONSE_RECEIVED больше не произойдёт. Почему? Потому что WinInet заботится о вас и полагает, что раз вы, после того как прочитали свои 50 байтов, больше ничего не попытались прочитать, то значит вам больше ничего и не нужно. И WinInet не станет отвлекать вас событием INTERNET_STATUS_RESPONSE_RECEIVED, вам ведь больше не интересно, что новые данные пришли, раз вы не попытались их прочитать, пока они ещё не пришли? Забавно да?
Понимаете, кака логика? Чтобы WinINet не прекращал сообщать вам о приходящих данных, вам нужно, в те моменты, когда данные в буфере кончились, а новые ещё не пришли, преднамеренно делать ошибочные попытки что-то читать из буфера.
Это не так просто, как кажется. Первый вопрос: сколько байтов просить, делая такие i-want-more-попытки? Тут на самом деле есть подводный камень. К тому моменту, когда вы будете делать fake-вызов (попытка прочитать, когда вы знаете,что читать нечего), данные в от сервера могут появится, и fake-вызов действительно что-то прочитает. Проблема в том, что вы уже прочитали эти данные, но о том, что они пришли, узнаете чуть позже
И, скорее всего, когда узнаете, вы захотите их опять прочитать.
Мораль Если вы ждёте ответ от сервера, этот ответ не имеет конкретной длины, а сервер отвечает маленькими блоками с большим временным промежутком, вы испытаете много проблем.
Так что юзайте сокеты (боже, я это говорю?) или новую библиотеку WinHTTP, которая доступна только начиная с WinXP SP1 или Win2k SP3.