使用TCP连接从HTTP服务器获取数据,在极少数情况下存在垃圾数据

lee*_*ade 1 c++ tcp winsockets winsock2 http-headers

我正在使用Winsocks 2.2编写一个使用Visual Studio 2010的C++网络游戏,并决定使用我的网络服务器存储游戏的活动服务器列表是个好主意.当服务器启动时,它将在我的Web服务器上注册,退出时取消注册; 当有人访问服务器列表时,服务器本身将尝试清理列表(这种行为我仍在设计不涉及服务器上的太多工作;但我想当游戏服务器试图添加自己时,我的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");
Run Code Online (Sandbox Code Playgroud)

我期待回到格式正确的数据,我并没有完全得到.这是我得到的:

2f
Server Count:1
129.21.138.1,40000,Depth of Hell
0
Run Code Online (Sandbox Code Playgroud)

这是一些带有所有头信息的垃圾的另一个输出:

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
Run Code Online (Sandbox Code Playgroud)

这是我的输出应该是什么样的,我偶尔会得到这个,但不是所有的时间:

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
Run Code Online (Sandbox Code Playgroud)

我认为这不重要,但这是我在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'];
}
Run Code Online (Sandbox Code Playgroud)

这里有一些涉及接收字符串的代码(是的,它现在有点裸骨,我意识到我可以使用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;
Run Code Online (Sandbox Code Playgroud)

那么,你们中的任何人都知道这个垃圾数据来自哪里?

编辑:查看正确的标题信息后,垃圾邮件有"Transfer-Encoding:chunked",并且没有"内容长度"....到底是怎么回事?

小智 6

所谓的"垃圾"实际上是来自服务器的分块数据.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规范...

  • 我相信规范指的是从HTTP服务器接收数据的任何程序,所以你的数据恐怕会被计算在内.(也许你可以配置服务器不使用分块编码发送数据 - 但我怀疑它,因为规范说服务器可以假设所有客户端都支持它,那么重点是什么?)祝你好运; 我写了一个非常简单的HTTP服务器,甚至为此,HTTP规范比我预期的更烦人. (2认同)