InternetReadFile завершается с ошибкой из-за фрагментированного ответа

У меня есть сервер, который отправляет данные кодирования передачи по частям. Я использую InternetReadFile для чтения данных, но InternetReadFile завершается с ошибкой 12004 после чтения первого фрагмента. Я использовал скрипач (Wireshark) для перехвата полученных данных. Wireshark отображает второй фрагмент, но InternetReadFile API не работает.

Образец кода :

    CString totalbuffer ;

    While ( 1 )
    {
      char recv [ 10 ] = '\0' ;
      DWORD dwBytesRead = 0 ;
      if ( InternetReadFile ( httpSocket.hReq , recv, 10 , &dwBytesRead ) )
      {
         recv[ dwBytesRead] = '\0' ;
         totalbuffer += recv ;
         printf ( " received buffer : %s" , recv ) ;
         return 1 ;
      }
      else
      {
         printf ( " InternetReadFile failed with : %d" , GetLastError ( ) ) ;
         return 0 ;
      }
    };  

WireShark отображает:

HTTP/1.1 200 ОК

Передача-кодирование: по частям

Дата: Чт, 18 сентября 2014 г., 14:16:16 по Гринвичу

Сервер: ЧНД

3

Ok\n

3

CMD

Клиент читает только первые 3 байта блока. Когда я пытаюсь прочитать следующий 3-байтовый фрагмент «CMD», он не работает.

Пожалуйста, помогите с тем, какие необходимые изменения должен сделать клиент? или сервер должен обрабатывать что-то дополнительное?


person Anantha Subramaniam    schedule 19.09.2014    source источник
comment
Связано: вы знаете, что первые 10 байтов, которые вы читаете, если этот буфер полностью заполнен, строка сразу после вызовет неопределенное поведение, превысив размер вашего массива на один элемент. (т. е. dwBytesRead == 10 плохо для recv[dwBytesRead] = '\0';, когда массив имеет ширину всего 10 элементов (и, следовательно, индексируется только от 0..9).   -  person WhozCraig    schedule 19.09.2014


Ответы (1)


У меня была аналогичная проблема, вам нужно «запросить» соединение для получения дополнительной информации, используя InternetQueryDataAvailable():

  while(TRUE)
  {
    res = InternetQueryDataAvailable(hr, &len, 0, 0);
    if (!res || len == 0) break;

    res = InternetReadFile(hr, recv, len, &dwbread);
    if(!res || (res && dwbread == 0)) break;
    totalbuffer += recv ;
    ...
  }

Используя его, он увидит, есть ли еще данные, поступающие из этого HTTP-запроса, и это, похоже, позаботится о кодировании по частям, поскольку количество байтов (длина «куска») не будет отображаться в буфере recv, поэтому мы не можем использовать его в необработанном виде.

Примечание: моя программа написана на C, а не на C++, но суть вы уловите.

person ndrix    schedule 13.07.2015