Я загружаю файл с url с помощью socket.h, и когда я пытаюсь вывести содержимое буфера, я получаю только его части. Вот файл, основной json файл. http://82.80.47.90/WarningMessages/alerts.json
Связанный код -
size_t MAX_DATA_LENGTH = 50001;
char bufIn[MAX_DATA_LENGTH];
dataLength = recv(sockfd, bufIn, MAX_DATA_LENGTH-1, 0);
bufIn[dataLength] = '\0';
std::cout << "client: received data length " << dataLength << std::endl << bufIn;
Мой консольный вывод, когда я запускаю его -
HTTP для oref.org.il:
Отправлено. клиент: полученная длина данных 524
HTTP/1.1 200 OK
Cache-Control: max-age = 4 Content-Length: 174 Content-Type: application/json
Последнее изменение: Вт, 15 июл 2014 08:43:22 GMT
Accept-Ranges: байт
ETag: W/"6bad3d68a0cf1: 2d5"
Сервер: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Дата: Вт, 15 Июл 2014 08:44:45 GMT
Set-Cookie: cookie1 = KI4GAQVLKVW4JFN90R6B9GAANOO8HAYR; Path =/{
Хотя... Когда я нюхаю пакеты, выход -
{"id": "1405424602778", "title": "", "data": []}
Или:
0000 ff fe 7b 00 20 00 0d 00 0a 00 22 00 69 00 64 00 ..{. .....".i.d.
0010 22 00 20 00 3a 00 20 00 22 00 31 00 34 00 30 00 ". .:. .".1.4.0.
0020 35 00 34 00 32 00 34 00 36 00 30 00 32 00 37 00 5.4.2.4.6.0.2.7.
0030 37 00 38 00 22 00 2c 00 0d 00 0a 00 22 00 74 00 7.8.".,.....".t.
0040 69 00 74 00 6c 00 65 00 22 00 20 00 3a 00 20 00 i.t.l.e.". .:. .
0050 22 00 e4 05 d9 05 e7 05 d5 05 d3 05 20 00 d4 05 "........... ...
0060 e2 05 d5 05 e8 05 e3 05 20 00 d4 05 ea 05 e8 05 ........ .......
0070 e2 05 d4 05 20 00 d1 05 de 05 e8 05 d7 05 d1 05 .... ...........
0080 20 00 22 00 2c 00 0d 00 0a 00 22 00 64 00 61 00 .".,.....".d.a.
0090 74 00 61 00 22 00 20 00 3a 00 20 00 5b 00 5d 00 t.a.". .:. .[.].
00a0 0d 00 0a 00 7d 00 0d 00 0a 00 0d 00 0a 00 ....}.........
Я бы действительно попросил вас помочь. Я пытался изменить кодировку, но кодировка UTF-8, поэтому нет смысла ее менять.
Благодарю!
Вы отправляете cout
const char*
в bufIn
, так что единственный способ, которым cout
может судить, - это найти первый байт NUL: ваши данные не ASCII, поэтому он попадает в байты "ff fe 7b 00" и останавливает его вывод. Если вы хотите избежать того, что вы можете либо принудительно послать NULs терминалу с помощью cout.write(bufIn, dataLength)
, либо cout.write(bufIn, dataLength)
итерацию по данным, напечатающим isprint()
-able, и печатать значение \
восьмеричное значение или что угодно другие обозначения, которые вам нравятся.
Кроме того, TCP является протоколом байтового потока, что означает, что любые данные, которые вы пытаетесь прочитать, могут быть доставлены вам в небольших разделах с единственной необходимой детализацией на уровне байтов. Если вы повторно получаете один раз и получаете только часть данных, вы должны снова зацикливаться и возвращаться, пока не получите все, что ожидаете/нуждаетесь (или EOF/disconnect/error). Это ваша задача, чтобы собрать эти данные или каким-либо образом справиться с этим, чтобы удовлетворить ваши потребности. Некоторые функции API позволяют блокировать до тех пор, пока не будет получено определенное количество байтов (или EOF/disconnect/error), но это не нормальное поведение. Прочтите справочную страницу для recv
и посмотрите несколько примеров, но кратко:
size_t MAX_DATA_LENGTH = 50001;
char bufIn[MAX_DATA_LENGTH];
size_t position = 0;
size_t dataLength;
while ((dataLength = recv(sockfd, bufIn + position, MAX_DATA_LENGTH-position-1, 0)) > 0)
position += dataLength;
dataLength = position;
bufIn[dataLength] = '\0';
Не самый чистый код, но это общая идея.