Вы вызываете recv()
в цикле до тех пор, пока сокет не отключится или не сработает (и неправильно записал полученные данные в ваш поток), сохранив все необработанные данные в вашем буфере char*
. Это неверный способ чтения HTTP-ответа, особенно если используются HTTP-алименты (в этом случае в конце ответа не произойдет отключение). Вы должны следовать правилам, изложенным в RFC 2616 . А именно:
"\r\n\r\n"
. Пока не читайте байты. Connection: close
если ответ использует HTTP 1.1 или отсутствие заголовка Connection: keep-alive
, если ответ использует HTTP 0.9 или 1.0. Если обнаружено, закройте конец соединения сокета, потому что сервер закрывает его конец. В противном случае, держите соединение открытым и повторно использовать его для последующих запросов (если вы не сделали это с помощью соединения, и в этом случае его закрыть). Короче говоря, вам нужно сделать что-то более похожее на это (псевдокод):
string headers[];
byte data[];
string statusLine = read a CRLF-delimited line;
int statusCode = extract from status line;
string responseVersion = extract from status line;
do
{
string header = read a CRLF-delimited line;
if (header == "") break;
add header to headers list;
}
while (true);
if ( !((statusCode in [1xx, 204, 304]) || (request was "HEAD")) )
{
if (headers["Transfer-Encoding"] ends with "chunked")
{
do
{
string chunk = read a CRLF delimited line;
int chunkSize = extract from chunk line;
if (chunkSize == 0) break;
read exactly chunkSize number of bytes into data storage;
read and discard until a CRLF has been read;
}
while (true);
do
{
string header = read a CRLF-delimited line;
if (header == "") break;
add header to headers list;
}
while (true);
}
else if (headers["Content-Length"] is present)
{
read exactly Content-Length number of bytes into data storage;
}
else if (headers["Content-Type"] == "multipart/byteranges")
{
string boundary = extract from Content-Type header;
read into data storage until terminating boundary has been read;
}
else
{
read bytes into data storage until disconnected;
}
}
if (!disconnected)
{
if (responseVersion == "HTTP/1.1")
{
if (headers["Connection"] == "close")
close connection;
}
else
{
if (headers["Connection"] != "keep-alive")
close connection;
}
}
check statusCode for errors;
process data contents, per info in headers list;