Я начинаю использовать сокеты на языке программирования Си. Я пытаюсь сделать простой http-запрос и сохранить буфер, полученный из read () в моем буфере. Для этого я использую указатели / realloc()
, программы на C работают нормально, не компилируют ошибок, но читают только часть ответа http.
Например, если я попытаюсь получить бинарный файл логотипа Google: http://www.google.com/images/srpr/logo3w.png Content-Length скажет 7007 байт, но strlen(buffer)
скажет 5146 для меня. Я считаю, что ошибка здесь - моя buf_size
и realloc()
почему bytesreaded
равно 7337, а 330 байт, как я полагаю, имеет заголовки.
Вот мой код:
char *
httpget(const char * domain, const int port, const char * headers)
{
int sockfd; /* Socket file descrption */
int buf_size = MAX_BUFFER_SIZE;
struct sockaddr_in sock_addr;
struct hostent * host;
char * buffer;
char * newbuf;
char * tbuf;
sockfd = socket(AF_INET, /* Uses IPV4 Internet protocols */
SOCK_STREAM, /* Uses the TCP (Transfer Communication Protocol) */
0 /* "0" for socket () function choose the correct protocol based on the socket type. */
);
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 + bytesloaded, tbuf, readed);
bytesloaded += readed;
}
//printf("bytesreaded = %d and buffer len is %d\n", bytesloaded, strlen(buffer));
free(tbuf);
close(sockfd);
return buffer;
}
, то:
char * domain = "www.google.com\0";
char * sheaders = "GET /images/srpr/logo3w.png HTTP/1.1\r\nHost:www.google.com\r\nConnection:close\r\n\r\n\n\0";
int port = 80;
char * response = httpget(domain, port, sheaders);