Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2012, 01:38   #1
olgnet
 
Регистрация: 06.07.2012
Сообщений: 4
По умолчанию Сокеты - загрузка содержимого сайта

Здравствуйте, использую linux(т.е. winAPI не предлогать) и компилятор g++... Хочу с помощью сокетов получить ответ от сервера(nginx), но любой сервер отдаёт ошибку 400 bad request, помогите найти ошибку. Заранее очень благодарен за помощь! Код:
Код:
#include <stdlib.h>
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/in.h>
#include <assert.h>
#include <stdio.h>
#include <sstream>
using namespace std;
int main()
{
    char site[] = "nixmail.ru";
    char message[] = "GET / HTTP/1.1\r\nHost: nixmail.ru\r\n
User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5) Gecko/2008050509 Firefox/3.0b5\r\n
Accept: text/html\r\nConnection: close\r\n";
    int sock;
    char buf[1024];
    struct sockaddr_in addr;
    struct hostent* host = gethostbyname(site);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = ((in_addr*)host->h_addr_list[0])->s_addr;
    if(connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(2);
    }
 
    send(sock, message, sizeof(message), 0);
    recv(sock, buf, sizeof(buf), 0);
    cout << buf << endl;
    close(sock);
    return 0;
}

Последний раз редактировалось rpy3uH; 06.07.2012 в 08:04.
olgnet вне форума Ответить с цитированием
Старый 06.07.2012, 03:01   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

как минимум не хватает еще одной пары \r\n в конце запроса.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 06.07.2012 в 03:04.
veniside вне форума Ответить с цитированием
Старый 06.07.2012, 15:29   #3
olgnet
 
Регистрация: 06.07.2012
Сообщений: 4
По умолчанию

Огромное спасибо! Помогло... Только ответ приходит не полностью, только часть, пробовал увеличивать размер buf до 524288, но всё равно та же часть от ответа... В чём может быть проблема?
olgnet вне форума Ответить с цитированием
Старый 06.07.2012, 16:43   #4
olgnet
 
Регистрация: 06.07.2012
Сообщений: 4
По умолчанию

Насколько я понял проблема в том что recv не успевает получить все данные... Как реализовать проверку получен ли весь ответ или нет? Насколько я понял нужно смотреть на последний символ и сравнивать его с \0 ? Или есть другой способ? Заранее очень благодарен за помощь!!
olgnet вне форума Ответить с цитированием
Старый 06.07.2012, 16:58   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

курите описание протокола HTTP


в двух словах:

раз указано "Connection: close", то по-простому можно принимать данные, пока сервер не закроет сокет.

а по-хорошему, получаем заголовки ответа, заголовки оканчиваются \r\n\r\n
сразу после заголовков идут данные
размер данных указывается в заголовке Content-Lenght:
если такого заголовка нет, то получаем данные, пока сокет не закроется.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 06.07.2012, 18:23   #6
olgnet
 
Регистрация: 06.07.2012
Сообщений: 4
По умолчанию

Ну мне надо хотя бы разобраться с тем как принять ответ полностью, нужно делать бесконечный цикл в котором recv принимает ответ и если в ответе пустота то останавливать цикл? Потом разделять ответ на подстроки по \r\n\r\n, второй элемент и будет содержимое сайта... Так? А нет ли примера такое реализации, наверняка кто-то уже сталкивался)))
olgnet вне форума Ответить с цитированием
Старый 06.07.2012, 20:13   #7
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Некоторые серверы любят выдавать Transfer-Encoding: chunked - здесь уже по \r\n\r\n необязательно конец. Так что RTFM.
Somebody вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сохранение содержимого в файл и дальнейшая ее загрузка xrenomx Общие вопросы Delphi 4 02.08.2011 12:10
Загрузка сайта Onni JavaScript, Ajax 2 28.04.2011 22:43
Загрузка содержимого txt в ListView foxes Общие вопросы Delphi 6 27.04.2011 00:07
Загрузка изображений с сайта Johnson Работа с сетью в Delphi 2 28.08.2009 13:28
Загрузка содержимого txt в ListView Rendll Компоненты Delphi 2 26.03.2009 11:04