Winsock recv缓冲区错误

时间:2014-04-17 15:36:45

标签: c++ sockets visual-c++ winsock

尝试用Visual C ++来理解winsocket的工作 这是我的代码:

while (true) {
    char l[1];
    recv(tsock.sock, l, 1, 0);
    std::cout << l << std::endl;
    if (!l)
    {
        return;
    }
}

但是当我试着去google.com:80 http获取查询时我得到了什么:

Connected
Sending request to host
H╠╠╠╠╠╠╠╠
T╠╠╠╠╠╠╠╠☺
T╠╠╠╠╠╠╠╠☻
P╠╠╠╠╠╠╠╠♥
/ ╠╠╠╠╠╠╠╠♦
1╠╠╠╠╠╠╠╠♣
.╠╠╠╠╠╠╠╠♠
0╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠
3╠╠╠╠╠╠╠╠
0╠╠╠╠╠╠╠╠

2╠╠╠╠╠╠╠╠♂
╠╠╠╠╠╠╠╠♀
F╠╠╠╠╠╠╠╠
o╠╠╠╠╠╠╠╠♫
u╠╠╠╠╠╠╠╠☼
n╠╠╠╠╠╠╠╠►
d╠╠╠╠╠╠╠╠◄
╠╠╠╠╠╠╠╠↕

╠╠╠╠╠╠╠╠‼
C╠╠╠╠╠╠╠╠¶
...

有很多垃圾回收了。但是当我将缓冲区形式1个单元格的声明更改为2时,所有内容似乎都变得更加有效。 代码

while (true) {
    char l[2];
    memset(&l, 0, sizeof(l));
    recv(tsock.sock, l, 1, 0);
    std::cout << l << std::endl;
    if (!l)
    {
        return;
    }
}

结果:

ConnectedSending request to hostHTTP / 1.0 302 Found
Cache - Control: private
Content - Type : text / html; charset = UTF - 8
Location: http ://www.google.ru/?gfe_rd=cr&ei=r_RPU4yzJ8GdwAOWjoDoAQ
Content - Length : 258
Date : Thu, 17 Apr 2014 15 : 35 : 11 GMT
Server : GFE / 2.0
Alternate - Protocol : 80 : quic

<HTML><HEAD><meta http - equiv = "content-type" content = "text/html;charset=utf-8">
<TITLE>302 Moved< / TITLE>< / HEAD><BODY>
<H1>302 Moved< / H1>
The document has moved
<A HREF = "http://www.google.ru/?gfe_rd=cr&amp;ei=r_RPU4yzJ8GdwAOWjoDoAQ">here< / A>
.
< / BODY>< / HTML>

这件事的成交是什么?

1 个答案:

答案 0 :(得分:1)

这里的主要问题是你使用一个字符数组(即使它只是一个单个字符的数组),输出操作符将其解释为字符串。正如您应该知道的那样,所有字符串都需要由特殊字符'\0'终止,该字符可以在您阅读的字符后的内存中的任何位置。

相反,您应该使用单个char变量,并在接收时使用address-of运算符:

char l;
recv(tsock.sock, &l, 1, 0);

或者,您可以使用更大的数组并使用recv中返回的值来知道字符串终止符的放置位置:

char l[1025];  // 1024 +1 for terminator
int rsz = recv(tsock.sock, l, sizeof(l) - 1, 0);  // -1 for terminator
if (rsz > 0)
{
    l[rsz] = '\0';  // Terminate string
    std::cout << l << std::flush;
}
else
{
    // Handle closed connection, or errors
}

我实际上推荐这第二个选项。您不仅会检查错误并关闭连接,还会更有效。