Использование TCP-соединения для получения данных с HTTP-сервера, в редких случаях появляются данные с мусором - PullRequest
1 голос
/ 13 апреля 2011

Я пишу сетевую игру на C ++, используя Winsocks 2.2, используя Visual Studio 2010, и решил, что было бы неплохо использовать мой веб-сервер для хранения списка активных серверов для игры.Когда сервер запускается, он регистрируется на моем веб-сервере, при выходе отменяется регистрация;и сам сервер будет пытаться очистить список, когда кто-то получит доступ к списку серверов в зависимости (это поведение, которое я все еще работаю над проектированием, чтобы не включать слишком много работы на сервере; но я подумал, когда игровой сервер пытается добавить себя, мойФайл php будет использовать fsockopen, чтобы определить, может ли он на самом деле получить доступ к серверу из внешней сети, в противном случае сервер не будет добавлен, пока он не сможет правильно настроить переадресацию портов или каким-либо образом решить проблему).

Хорошо, после некоторого исследования я выяснил, как получить что-то от сервера, использующего соединение TCP, от форматирования специального сообщения для сервера HTTP.Вот что у меня есть:

if(FAIL == Connection::Get_Connection(&m_Connection, networkSettings.ServerListAddress, 80))
{
    return FAIL;
}

m_Connection.SendMsg("GET /servers.php HTTP/1.1\r\nHost: cyclotron.leetnightshade.com\r\nUser-Agent: CycloTron\r\n\r\n");

Я ожидаю обратно правильно отформатированные данные, которые я точно не получаю.Вот что я получаю:

2f
Server Count:1
129.21.138.1,40000,Depth of Hell
0

Вот еще один вывод некоторого мусора со всей информацией заголовка:

HTTP/1.1 200 OK
Date: Tue, 12 Apr 2011 23:23:11 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=8254688ee345202bd177d57e4ba339b2; path=/
Set-Cookie: PHPSESSID=73eae89f61e7268f433af9bdfe299173; path=/
Set-Cookie: PHPSESSID=8fb5d6fd9f1023bb00290b4daa3c7952; path=/
Connection: close
Transfer-Encoding: chunked
Content-Type: text; charset=us-ascii

e
Server Count:1
21

129.21.138.1,40000,Depth of Hell
0

Вот так должен выглядеть мой вывод, и яиногда получаю это, но не всегда:

HTTP/1.1 200 OK
Date: Tue, 12 Apr 2011 23:32:13 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: PHPSESSID=a3c88c2d96d45c6f6d3b029e095c429a; path=/
Set-Cookie: PHPSESSID=bf19734ff60813d6d0a5ba944410356a; path=/
Set-Cookie: PHPSESSID=c36a2d9e12c81d4a19a7f41dc5522b4e; path=/
Content-Length: 47
Connection: close
Content-Type: text; charset=us-ascii

Server Count:1
129.21.138.1,40000,Depth of Hell

Я не думаю, что это имеет большое значение, но это мой PHP-код на веб-сервере:

$num = mysql_num_rows($result);
echo 'Server Count:'.$num;

while ($row = mysql_fetch_assoc($result))
{
    // TODO: check date of entry, if it's really old, remove it.
    echo PHP_EOL.$row['address'].','.$row['port'].','.$row['displayName'];
}

А вот и некоторый код, включающий получение строки (да, на данный момент это немного обнажено, и я понимаю, что могу использовать функцию cstring для поиска двух новых строк, поэтому мне не нужно делать копирование строки,Я просто пытаюсь использовать строки, чтобы упростить задачу):

memset(m_MsgBuffer, 0, sizeof (char) * M_BufferSize);

m_Received = recv(m_Connection.M_Socket, m_MsgBuffer, M_BufferSize, 0);

m_MsgBuffer[m_Received] = '\0';

string str = string(m_MsgBuffer);

size_t index = str.find("\r\n\r\n");
str.erase(0,index);

std::cout << "Received message: " << str << std::endl;

Итак, у кого-нибудь из вас есть идея, откуда поступают эти данные мусора?

РЕДАКТИРОВАТЬ: После просмотра правильной информации заголовка, с мусором имеет «Transfer-Encoding: chunked» и не имеет «content-length».... что происходит?

1 Ответ

6 голосов
/ 13 апреля 2011

Так называемый «мусор» на самом деле представляет собой фрагментированные данные с сервера.Сервер HTTP / 1.1 может свободно отправлять данные обратно в виде фрагментов, если это того требует, и спецификация HTTP / 1.1 довольно ясна: «Все приложения HTTP / 1.1 ДОЛЖНЫ иметь возможность принимать и декодировать« фрагментированное »кодирование передачи».

Подробности кодирования по частям описаны в спецификации HTTP / 1.1:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1

Если вы пишете клиент HTTP, вам нужно прочитать HTTPспекуляция ...

...