Как загрузить бинарный файл (в данном случае изображение) с веб-сервера, используя сокеты C? - PullRequest
0 голосов
/ 06 октября 2019

Хорошо, поэтому в основном мне нужно загрузить изображение .jpg или .png с веб-сервера с использованием сокетов C.

Я делаю небольшое приложение для домашнего пользователя для Wii, с помощью которого вы можете просматривать Reddit. Программа уже получает сообщения с первой страницы, используя HTTP-запрос, но я не могу понять, как я могу загрузить изображение. За последние несколько дней я пробовал несколько вещей и ничего не понимаю.

Вот что я реализовал до сих пор:

(net_read или net_write эквивалентны чтению или записи в linux, этотак что он работает в Wii)

struct post {
    char author[25];
    char subreddit[25];
    char title[300];
    char url[300];
    int score;
}; //Included this for context

struct post i = fp_data[index]; //Getting data from received posts

char* url = malloc(300*sizeof(char));
strcpy(url, i.url);
url+=8; //Remove 'http://'
char* tempurl = malloc(300*sizeof(char)); //tempurl so strtok doesn't screw with the url
strcpy(tempurl, url);

int portno = 80;
char delimiter[] = "/";
char *host = strtok(tempurl, delimiter);
char *requestend = url;
requestend+=strlen(host);
// example values:
// host = i.imgur.com
// requestend = /ROQnhvC.jpg

    if(strstr(url,".png") != NULL){
        struct hostent *server;
        struct sockaddr_in serv_addr;
        int sockfd, bytes, sent, total, message_size;
        char *message;
        char response[1024] = {0};

        message_size=0;
            message_size+=strlen("GET  HTTP/1.1\r\nHost: \r\n")+strlen(requestend)+strlen(host);
            message_size+=strlen("Connection: Keep-Alive\r\n\r\n");

        message=malloc(message_size);
            sprintf(message,"GET %s HTTP/1.1\r\nHost: %s\r\n",requestend, host);
            strcat(message,"Connection: Keep-Alive\r\n\r\n");

        printf("Request:\n%s\n",message);

        sockfd = net_socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) printf("ERROR opening socket");

        //int yes = 1;
        //net_setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(int));

        server = net_gethostbyname(host);
        if (server == NULL) printf("ERROR, no such host");

        memset(&serv_addr,0,sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(portno);
        memcpy(&serv_addr.sin_addr.s_addr,server->h_addr,server->h_length);

        if (net_connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
            printf("ERROR connecting");

        total = strlen(message);
        sent = 0;
        do {
            bytes = net_write(sockfd,message+sent,total-sent);
            if (bytes < 0)
                printf("ERROR writing message to socket");
            if (bytes == 0)
                break;
            sent+=bytes;
        } while (sent < total);

        FILE* fp;
        char pth[20];
        sprintf(pth, "sd://tex%d.png", index); 
        fp = fopen(pth, "wb"); //Writing to a file so I can see the results
        int n = 0;

        n = net_read(sockfd, response, 1024);

        if(n < 1){
            printf("read() failed");
            return;
        }
        char* ss = strstr(response, "\r\n\r\n")+4; //Cut '\r\n\r\n' so the http response is gone
        fwrite(ss, sizeof(char), strlen(ss), fp);

        while((n = net_recv(sockfd, response, 1024, 0)) >= 1){
            fwrite(response,sizeof(response),1,fp);
            memset(response, 0, sizeof(response));
            if(n < 1024){
                break;
            }
        }

        fclose(fp);
        net_close(sockfd);
    }

Это должно вернуть действительный файл .jpg, но это не работает. Если я помещу необработанные данные рядом с необработанными данными исходного файла, между ними будут большие различия. Также я не могу просмотреть это. В чем здесь проблема?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...