Reputation: 183
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&ei=r_RPU4yzJ8GdwAOWjoDoAQ">here< / A>
.
< / BODY>< / HTML>
What the deal of this thing?
Upvotes: 0
Views: 135
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