как использовать функцию memcpy ()? - PullRequest
1 голос
/ 27 марта 2012

Я пытаюсь сохранить некоторые двоичные данные, полученные из read () в моем буфере, используя функцию memcpy ().

По сути, я хочу сохранить buf в моем буфере:

#define MAX_BUFFER_SIZE 256
//...
char *
httpget(const char * domain, const int port, const char * headers)
{
    int sockfd;
    int buf_size = MAX_BUFFER_SIZE;

    struct sockaddr_in  sock_addr; 
    struct hostent  *   host;

    char * buffer;
    char * newbuf;
    char * tbuf;

    sockfd = socket(AF_INET,SOCK_STREAM,0);

    if( sockfd == -1 )
    {
        return NULL;
    }

    host = gethostbyname(domain);

    if( NULL == host )
    {
        close(sockfd);
        return NULL;
    }

    memset(&sock_addr, '\0', sizeof(sock_addr));
    sock_addr.sin_family = AF_INET;
    memcpy( &sock_addr.sin_addr.s_addr,
            host -> h_addr,
            host -> h_length );

    sock_addr.sin_port = htons(port);

    if( connect(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) == -1)
    {
        close(sockfd);
        return NULL;
    }

    if( write(sockfd, headers, strlen(headers) + 1) == -1)
    {
        close(sockfd);
        return NULL;
    }

    buffer = malloc( MAX_BUFFER_SIZE );
    tbuf = malloc( MAX_BUFFER_SIZE );

    if(buffer == NULL || tbuf == NULL)
    {
        return NULL;
    }

    int bytesloaded = 0;
    int readed;

    while( (readed = read(sockfd, tbuf, MAX_BUFFER_SIZE)) > 0 )
    {   
        if(bytesloaded + readed >= buf_size)
        {
            buf_size = buf_size + MAX_BUFFER_SIZE;  
            newbuf = realloc(buffer, buf_size);

            if(newbuf != NULL)
            {
                buffer = newbuf; 
            }
            else 
            {
                return NULL;
            }
        }

        memcpy(buffer, tbuf, readed);
        bytesloaded += readed;
    }

    close(sockfd);
    printf("buffer = %s", buffer);
    return buffer;
}

но когда я печатаюf ("% s", буфер); Я получаю только заголовки HTTP и �PNG символов из двоичного файла, которые имеют длину содержимого 7007. как это исправить? Я надеюсь, что это понятно для вас. любая помощь очень ценится. Спасибо заранее.

Ответы [ 3 ]

3 голосов
/ 27 марта 2012

Я думаю, что вы хотите:

memcpy(buffer + bytesloaded, buf, readed);

Вы не видите весь ответ, когда пытаетесь вывести его с помощью printf("%s",buffer), потому что изображение .png, отправляемое в ответе, является двоичными данными, которыескорее всего, содержит нулевой '\0' байт, и printf() остановится на этом этапе.

У вас есть все другие варианты для проверки данных, возвращаемых в ответе (или информации об этом): lookв buffer в отладчике выведите дамп переменной bytesloaded, дамп buffer, используя функцию, которая преобразует его в шестнадцатеричный формат для отображения, и / или запишите тело ответа (после заголовков и CR / LF, следующих зазаголовки) к файлу .png и посмотрите на него во что-то, что покажет изображение.

1 голос
/ 27 марта 2012

Поскольку директива форматирования printf(3) %s будет печатать байты в виде символов, пока не встретит символ ASCII NUL. Формат PNG может позволить NUL, возможно, сразу после девятого байта - и первые восемь байтов - это 0x89, PNG, а затем некоторые пробельные символы для обнаружения определенных видов. искажения белого пространства.

Я предлагаю использовать другой спецификатор формата printf(3) для просмотра рассматриваемых данных - или записать их в файл отладки, чтобы вы могли редактировать их с помощью обычных шестнадцатеричных редакторов для проверки их содержимого.

1 голос
/ 27 марта 2012

В memcpy есть опечатка, ссылающаяся на buffe вместо буфера, и хотя возможно, что она появляется только в посте, а не в вашем реальном коде (я не верю, что он будет скомпилирован с ним), если это тогда это определенно проблема.

ОБНОВЛЕНИЕ: Хотя другие ответы предполагают, что может быть нулевой байт, в спецификации заголовка png нет места, где нулевой байт должен быть частью заголовка, поэтому единственное место, где он может быть, это тело, но так как вы данные не поступают, тогда единственным вариантом может быть, если это первая вещь в теле, что, на мой взгляд, на самом деле является задним регистром, так что вы можете попробовать использовать другой источник информации, такой как другое изображение или другой URL, и если проблема сохраняется на всех png-изображениях, тогда это что-то между printf и заголовком (и поэтому, если в заголовке есть нулевой байт, то это в любом случае стоит инвазировать).

Однако обратите внимание, что после букв PNG следует CRLF, а затем EOF, и хотя было бы интересно, если бы у printf возникла проблема, все же, если это проблема, то дамп в файл также не должен быть решением. если вы не откроете его с помощью программы просмотра png.

На самом деле вы не включили свой источник сокетов, и, таким образом, если код, который вы написали самостоятельно, убедитесь, что он не останавливается на первом EOF, поскольку он является частью заголовка png.

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