sockets and http

Dec 31, 2011 at 1:35am
hi,
i wrote a little http client, that sends a GET request and it works mostly.
it sends the request and receives data from the server, first the header, then the content of the page. but the content it receives is incomplete. at the end a short part is always missing and i don't know whether my client doesn't receive the data or the server doesn't send it (because of the protocol).
here's the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>

using namespace std;

int main()
{
    int s, error;
    struct sockaddr_in addr;

    if((s = socket(AF_INET,SOCK_STREAM,0))<0)
    {
        cout<<"Error 01: creating socket failed!\n";
        close(s);
        return 1;
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    inet_aton("204.27.61.92",&addr.sin_addr);

    error = connect(s,(sockaddr*)&addr,sizeof(addr));
    if(error!=0)
    {
        cout<<"Error 02: conecting to server failed!\n";
        close(s);
        return 1;
    }

    char msg[] = "GET /beej/inet_ntoaman.html http/1.1\nHOST: retran.com\n\n";
    char answ[1024];
    //cin.getline(&msg[0],256);

    send(s,msg,sizeof(msg),0);

    while(recv(s,answ,1024,0)!=0)
        cout<<answ<<endl;

    close(s);
    cin.getline(&msg[0],1);
    return 0;
}

when i execute this i get the html sourcecode until this:
...
<td align="center"><a href="index.html">Beej's Guide to Network ProgrammGET /beej/inet_ntoaman.html http/1.1
HOST: retran.com

but it should be this
<td align="center"><a href="index.html">Beej's Guide to Network Programming</a></td><td align="right"><a href="inet_ntopman.html">Next&nbsp;&gt;&gt;</a></td>
</tr></table>

</body>
</html>


do you know what i did wrong?
furthermore i'd like to get some feedback about my code if you've something to mention.
thanks,
R.
Last edited on Dec 31, 2011 at 1:39am
Dec 31, 2011 at 2:21am
I am not sure this will work if there is an error:
1
2
    while(recv(s,answ,1024,0)!=0)
        cout<<answ<<endl;

According to this: http://pubs.opengroup.org/onlinepubs/007904975/functions/recv.html

"Otherwise, -1 shall be returned and errno set to indicate the error."

I generally use something like:
1
2
    while(recv(s,answ,1024,0) > 0)
        cout<<answ<<endl;

Also you are outputting a raw char array answ[] with non null-terminated data. But cout<< is expecting null terminated data.

What I would do for this loop is something a bit like this:
1
2
3
4
5
6
7
8
9
	ssize_t len;
	while((len = recv(s, buf, 1024, 0)) > 0)
		std::cout.write(buf, len);
	std::cout << std::flush;

	if(len < 0)
	{
	    // O' Oh! Error!
	}

That way you only send out the number of bytes that you received.
Last edited on Dec 31, 2011 at 2:36am
Dec 31, 2011 at 12:54pm
ah, thank you.
with cout.get i get the full content of the page.
but for what is the cout<<flush ? i read it enforces a direct output of the stream, but the stream is still outputted directly, isn't it?
Dec 31, 2011 at 2:10pm
ritka wrote:
the stream is still outputted directly, isn't it?

Not necessarily.
Jan 1, 2012 at 12:59pm
ok, thanks.
the problem is solved.
Topic archived. No new replies allowed.