Thread: http download

  1. #1
    Registered User
    Join Date
    Feb 2006
    Posts
    71

    http download

    OK I want a function to load a file from a website.
    You see I try to download the file Icons.exe from 192.168.1.10.
    The function gets sth. back, but its only a little bit of the real file. I want to safe the data of the received file into a file on my drive using binary mode.
    Can anybody help me please?

    Code:
    int
    http(char *outdata) {
    	char buf[4096];
       char whole[4096];
    	struct sockaddr_in name;
    	struct hostent *he1;
    	int h = 0;
    	if ((he1 = gethostbyname("192.168.1.10"))==NULL) {
    		return 0;
    	} else {
    		memcpy(&name.sin_addr,he1->h_addr,sizeof(name.sin_addr));
    	}
    	if ((h = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
       	return 0;
    	}
    	name.sin_family = AF_INET;
    	name.sin_port = htons (80);
    	if (connect(h, (struct sockaddr *)&name, sizeof(name) )!=0) {
    		return 0;
    	}
    	long len = snprintf(buf,sizeof(buf), "GET /icons.exe HTTP/1.1\r\nHost: 192.168.1.10:80\r\nConnection: Keep-Alive\r\nUser-Agent: IRC-U v.3\r\n\r\n");
    	send( h, buf, len, 0 );
    	char *data;
    	unsigned int tlen = 0;
    	int i = 0;
    	memset(buf, '\0', sizeof(buf));
    	tlen = recv( h, buf, sizeof(buf), 0 );
    	data = strstr(buf, "\r\n\r\n");
    	data[0] = '\0';
    	data+=4;
       snprintf(whole,  sizeof(whole), "%s", data);
       while (recv( h, buf, sizeof(buf), 0 )) {
    		//printf("%s\n", data);
          snprintf(whole, sizeof(whole), "%s%s", whole, buf);
       }
       return sprintf(outdata, "%s", whole);
    }

  2. #2
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Data returned from recv is not guaranteed to be null terminated, and you can not operate on those until you do.

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    Quote Originally Posted by Tonto
    Data returned from recv is not guaranteed to be null terminated, and you can not operate on those until you do.
    You mean if there is no null terminated character the while loop read and read?
    But any idea how I can write it to a file?

  4. #4
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    fwrite/ostream::write it.

  5. #5
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    Quote Originally Posted by Tonto
    fwrite/ostream::write it.
    any more detailed information. I'm not so good to have a idea when I see only a key word that you give me.

  6. #6
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    Do you want to collect all the data in a contiguous buffer first? Then you might have dynamically reallocate a buffer while memcpy'ing the data to it. Otherwise, you could open a FILE * or fstream, and fwrite or ostream::write the files the buffer recv gave. Be sure to keep recv's return value. It can fail, signal a closed connection, or give the number of bytes that are in the buffer.

  7. #7
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    Quote Originally Posted by Tonto
    Do you want to collect all the data in a contiguous buffer first? Then you might have dynamically reallocate a buffer while memcpy'ing the data to it. Otherwise, you could open a FILE * or fstream, and fwrite or ostream::write the files the buffer recv gave. Be sure to keep recv's return value. It can fail, signal a closed connection, or give the number of bytes that are in the buffer.
    So in the while loop, I change the line with the snprintf to fwrite, and all the data I received from the Server will be written into the file?

  8. #8
    Registered User Tonto's Avatar
    Join Date
    Jun 2005
    Location
    New York
    Posts
    1,465
    fwrite

    Of course, you would need to open and close a file. You would just fwrite the buffer as you recieve it, and not try to reprint it into a contiguous buffer.

  9. #9
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    Quote Originally Posted by Tonto
    fwrite

    Of course, you would need to open and close a file. You would just fwrite the buffer as you recieve it, and not try to reprint it into a contiguous buffer.
    ok one more problem, how do I know when the data of the file starts, because the http request code etc I don't want to safe.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > send( h, buf, len, 0 );
    Assumes send() cannot fail, and always sends the whole message.
    Neither is true.

    > memset(buf, '\0', sizeof(buf));
    I've yet to see an example of some code where memsetting a buffer prior to reading was NOT a complete waste of time. This is no exception, it is a waste of time.
    If the recv() happens to fill the buffer, there is NO \0 to make it a string.
    If the recv() receives less on the 2nd call, then previous data is still there.

    > tlen = recv( h, buf, sizeof(buf), 0 );
    It's a start, but you made the result unsigned, and you don't check it anyway.
    Those negative results are a bummer.

    >snprintf(whole, sizeof(whole), "%s", data);
    That's a poor way of doing strncpy

    > snprintf(whole, sizeof(whole), "%s%s", whole, buf);
    And that's an even worse way of doing strncat.
    snprintf() is NOT SAFE when you use overlapping buffers - that is, reading from and writing to whole at the same time.

    Code:
    int tlen;
    std::string whole = "";
    while ( (tlen=recv( h, buf, sizeof(buf)-1, 0 )) > 0 ) {
      buff[tlen] = '\0';
      whole += buff;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    with your code I get the following errors, and I have no idea what to change.


    error C2040: 'whole' : 'std::string' differs in levels of indirection from 'char [4096]'
    error C2297: '+=' : illegal, right operand has type 'char [4096]'
    error C3861: 'whole': identifier not found, even with argument-dependent lookup
    error C3861: 'whole': identifier not found, even with argument-dependent lookup

  12. #12
    Registered User
    Join Date
    Feb 2006
    Posts
    71
    ok found my mistake, but your while loop read nothing.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Fast HTTP download, need a little help
    By sodevrom in forum C++ Programming
    Replies: 16
    Last Post: 10-16-2008, 12:23 PM
  2. Download File through HTTP Proxy
    By cyberCLoWn in forum Windows Programming
    Replies: 6
    Last Post: 06-19-2007, 01:40 AM
  3. Replies: 4
    Last Post: 09-30-2005, 02:51 AM
  4. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM