Alexander Bochkarev
Alexander Bochkarev

Reputation: 183

Winsocket resv buffer mistake

Trying to understand working of winsocket with Visual C++ Here the my code:

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

But what i got when tryin to get google.com:80 http get query:

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

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

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

There lot of trash recived. But when i change declaration of buffer form 1 cell to 2 and more everything seem to bee work greate. Code

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

And result:

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>

What the deal of this thing?

Upvotes: 0

Views: 135

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409364

The major problem here is that you use an array of characters (even if it's just an array of a single character), which the output operator interprets as a string. And as you should know, all strings needs to be terminated by the special character '\0', which can be anywhere in memory after the character you read.

Instead you should use a single char variable, and use the address-of operator when receiving:

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

Alternatively, you could use a larger array and use the returned value from recv to know where to put the string terminator:

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
}

I actually recommend this second option. Not only will you then check for errors and closed connection, it's also much more effective.

Upvotes: 2

Related Questions