1

Visual Studio 2010 を使用して、Winsocks 2.2 を使用して C++ でネットワーク ゲームを作成しています。Web サーバーを使用して、ゲームのアクティブなサーバーのリストを保存することをお勧めします。サーバーが起動すると、それ自体が Web サーバーに登録され、終了時に登録解除されます。誰かがサーバーリストにアクセスすると、サーバー自体がリストを消去しようとします(この動作は、サーバーであまり多くの作業を行わないように設計中ですが、ゲームサーバーが自分自身を追加しようとすると、 php ファイルは fsockopen を使用して、実際に外部ネットワークからサーバーにアクセスできるかどうかを検出します。そうでない場合は、ポート転送を適切にセットアップするか、何らかの方法で問題を解決できるまで、サーバーは追加されません)。

さて、いくつかの調査の後、HTTP サーバー用の特殊なメッセージをフォーマットすることで、TCP 接続を使用してサーバーから何かを取得する方法を見つけました。ここに私が持っているものがあります:

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

これはあまり重要ではないと思いますが、これは Web サーバー上の私の 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 関数を使用して 2 つの新しい行を探すことができるので、文字列のコピーを行う必要はありません。物事を簡単にするために文字列の使用に固執しようとしているだけです):

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」がありません。...何が起こっている?

4

1 に答える 1

6

いわゆる「ガベージ」は、実際にはサーバーからチャンク化されたデータです。HTTP/1.1 サーバーは、必要に応じてデータをチャンク形式で自由に送信できます。HTTP/1.1 の仕様は非常に明確です。 .

チャンク エンコーディングの詳細は、HTTP/1.1 仕様で説明されています。

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

HTTP クライアントを作成している場合は、HTTP 仕様を読む必要があります...

于 2011-04-12T23:49:29.673 に答える