User 13204940 Ответов: 2

C++ get request - необычная проблема


Привет,

Я написал некоторый код для выполнения запроса GET, и он работает до некоторой степени, за исключением того, что он не будет получать большие объемы данных должным образом. Это странно, потому что то, как я вывожу данные, похоже, определяет, сколько было получено.

У меня есть сервер, на который выполняется запрос GET, и я настроил его на вывод чисел от 0 до 9999 с помощью PHP-скрипта.

Работающий:
while (resp_len == BUFFER_SIZE)
{
	resp_len = recv(sock, (char*)&buffer, BUFFER_SIZE, 0);
		
	if (resp_len > 0)
	{
		string data = string(buffer).substr(0, resp_len);
		printf(data.c_str());
	}
}

Не работать:
while (resp_len == BUFFER_SIZE)
{
	resp_len = recv(sock, (char*)&buffer, BUFFER_SIZE, 0);
		
	if (resp_len > 0)
	{
		string data = string(buffer).substr(0, resp_len);
		response += data;
	}
}

printf(response.c_str());

В рабочем примере он последовательно возвращает 49 062 байта. С неудавшимся-всего 8372, и это тоже согласуется.

Мне нужен весь ответ в строке std::для возврата из этой функции. Не могли бы вы помочь мне разобраться в этом, пожалуйста?

Что я уже пробовал:

Несколько методов выполнения запросов GET, ни один из которых не работает отдельно от этого, и это темпераментно в зависимости от того, как выводятся данные.

Rick York

Что произойдет, если вы получите ответ меньше BUFFER_SIZE? Разве он не должен продолжаться, пока он получает какие-либо данные, т. е. resp_len > 0?

2 Ответов

Рейтинг:
6

User 13204940

Исправлено - когда я играл с кодом, я видел, что некоторые данные в конце повторяются, и я понял, что это было потому, что он пытался заполнить буфер для последнего фрагмента данных, даже если оставшиеся данные были недостаточно большими, поэтому он перечитал с начала этого фрагмента, чтобы заполнить буфер, и продублировал некоторые данные.

Эта версия считывает данные по частям, но пытается назначить только то, что доступно, а не всегда BUFFER_SIZE.

int nDataLength;

while ((nDataLength = recv(sock, (char*)&buffer, BUFFER_SIZE, 0)) > 0)
{
	for(int x = 0; x < nDataLength; x++)
	{
		response += buffer[x];
	}
}


Рейтинг:
2

Jochen Arndt

Ваш неработающий код слишком быстр (код выполняется быстрее, чем время, необходимое для получения BUFFER_SIZE байты). Первый код работает только потому, что printf() вызов требует некоторого времени для выполнения.

То recv() функция возвращает количество байтов, фактически доступных, вплоть до указанного размера буфера. Если вы вызовете его снова слишком быстро, возвращаемое значение будет меньше, чем BUFFER_SIZE.

Вам придется изменить свой код для получения данных до тех пор, пока не будет получен полный набор данных. Это может быть сделано с помощью конечного маркера (например, нулевого байта со строковыми данными) или путем отправки номера байтов в наборе данных сначала. Последнее обычно делается путем отправки определенного заголовка перед полезной нагрузкой. Определение таких заголовков и формата данных полезной нагрузки называется протокол.