1 Replies - 2630 Views - Last Post: 11 February 2012 - 02:39 AM

#1 tommynator128   User is offline

  • D.I.C Head
  • member icon

Reputation: 8
  • View blog
  • Posts: 127
  • Joined: 05-January 10

HTTP-Download

Posted 19 February 2010 - 02:25 AM

Description: only fstream,iostream,string,sstream and the unix/linux socket libraryDownloads a binary file from a web server to your computer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <sstream>

using namespace std;

#define BUF_SIZ 4096
#define HOST "localhost"


int send_request(const int sock, const char *hostname)
{
    char request[BUF_SIZ];
	
    snprintf(request, sizeof(request), "GET /datei.bin HTTP/1.1rnHost: localhostrnrn");
	
    if (send(sock, request, strlen(request), 0) == -1)
    {
        perror("send() failed");
        return 1;
    }
	
    return 0;
}

int view_response(const int sock)
{
    char response[BUF_SIZ];
    int bytes;
	int package = 0;
	int start = 0;
	int bytesWritten = 0;
	int cl = 0;

	string resp = "";
	
	time_t seconds1;
	seconds1 = time (NULL);
	
	
	ofstream outfile("datei.bin", ios_base::binary | ios_base::out);
    while((bytes = recv(sock, response, sizeof(response), 0)) > 0) {
        if (package == 0) {
            string sort = response;
            start = sort.find("rnrn");
			
			//falls man die Content-Length irgendwann mal brauchen kann
			int posA = sort.find("Content-Length: ")+16;
			int posB = sort.find("rn", posA)-posA;
			string cl_s(sort,posA,posB);
			cl = atoi(cl_s.c_str());
			
			
            size_t dataStart = start + strlen("rnrn");
            // Get the length of the data in this packet                        
            size_t dataLen = bytes - dataStart;
            // Write the data to the file                                       
            outfile.write(&response[dataStart], dataLen);
            bytesWritten = dataLen;
            package++;
        } else {
            outfile.write(response, bytes);
            bytesWritten += bytes;

        }
        cout << "datei.bin" << ": Wrote " << bytes << " bytes; "
		<< "total written: " << bytesWritten << endl;
    }
    outfile.close();
	cout << "Written: " << "datei.bin" << endl;
	
    if (bytes < 0)
    {
        perror("recv() failed");
        return 1;
    }
	
    return 0;
}

int main(int argc, char *argv[])
{
    struct hostent *host;
    struct sockaddr_in addr;
    int s;
	
	
    if (!inet_aton(HOST, &addr.sin_addr))
    {
        host = gethostbyname(HOST);
        if (!host)
        {
            herror("gethostbyname() failed");
            return 2;
        }
        addr.sin_addr = *(struct in_addr*)host->h_addr;
    }
	
    s = socket(PF_INET, SOCK_STREAM, 0);
    if (s == -1)
    {
        perror("socket() failed");
        return 3;
    }
	
	
    addr.sin_port = htons(80);
    addr.sin_family = AF_INET;
	
    if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
    {
        perror("connect() failed");
        return 4;
    }
	
	if (send_request(s, HOST)) {
		return 5;
	}
	if (view_response(s)) {
		return 6;
	}
	
    close(s);
	
    return 0;
}


Is This A Good Question/Topic? 0
  • +

Replies To: HTTP-Download

#2 Karel-Lodewijk   User is offline

  • D.I.C Addict
  • member icon

Reputation: 454
  • View blog
  • Posts: 864
  • Joined: 17-March 11

Re: HTTP-Download

Posted 11 February 2012 - 02:39 AM

You should respect Content-Length. Your current implementation will store everything the server sends after the header to the file, while only the first Content-length bytes after the header are guaranteed to be the contents of the file.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1