Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > Как правильно получать данные с web-страницы


Автор: quiz 17.10.2009, 23:25
Приложение должно циклично обращаться к определенному php-скрипту, который возвращает страницу с одной единственной записью типа "141;230;848". Эту запись нужно разделить по ";" и засунуть цифры в разные переменные и повторить все с начала.

Делаю я это примерно так:

Код

#define PORT 80
#define SERVERADDR "s.test.ru"

char buff[1000];
SOCKET my_sock;
sockaddr_in dest_addr;

String^ sendstr = "GET /run.php?id="+textBox2->Text+"&x="+xpos+"&y="+ypos+"&r="+rotate+" HTTP/1.0\r\nHost: s.test.ru\r\nConnection: Close\r\n\r\n";
char* buff2 = (char*)(void*)Marshal::StringToHGlobalAnsi(sendstr);


            // Шаг 1 - инициализация библиотеки Winsock
    if (WSAStartup(0x202, (WSADATA *)&buff[0]))
    {
        richTextBox1->AppendText("WSAStart error "+WSAGetLastError()+"\n");
    }

    // Шаг 2 - создание сокета
    my_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (my_sock < 0)
    {
        richTextBox1->AppendText("Socket() error "+WSAGetLastError()+"\n");
    }

    // Шаг 3 - установка соединения
    // заполнение структуры sockaddr_in - указание адреса и порта сервера

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    HOSTENT *hst;

    // преобразование IP адреса из символьного в сетевой формат
    if (inet_addr(SERVERADDR) != INADDR_NONE)
        dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR);
    else
    {
        // попытка получить IP адрес по доменному имени сервера
        if (hst = gethostbyname(SERVERADDR)) {
            ((unsigned long *)&dest_addr.sin_addr)[0] =
            ((unsigned long **)hst->h_addr_list)[0][0];
        } else    {
            richTextBox1->AppendText("Invalid address "+SERVERADDR+"\n");
            closesocket(my_sock);
            WSACleanup();
        }
    }

    // адрес сервера получен - пытаемся установить соединение
    if (connect(my_sock, (sockaddr *)&dest_addr, sizeof(dest_addr)))
    {
        //richTextBox1->AppendText("Connect error "+WSAGetLastError()+"\n");
    } else {
        //richTextBox1->AppendText("Соединение с "+SERVERADDR+" успешно установлено\n");
    }


// Шаг 4 - чтение и передача сообщений

int nsize;

send(my_sock, buff2, strlen(buff2), 0);
nsize = recv(my_sock, &buff[0], sizeof(buff) - 1, 0);

// тут парсинг buff[].... //

WSACleanup();



Если выполнять весь этот код каждый раз, то данные с сервера получаются без проблем, но слишком медленно. На одном компьютере обмен с сервером идет по 3 раза в секунду, а на более слабых - до 1 раза в 5 секунд.. никуда не годится.
Первая мысль - не нужно каждый раз выполнять создание сокета, получение ip, коннект и т.п. Сделал все коннекты и прочее один раз, и циклично повторял только этот кусок:

Код

send(my_sock, buff2, strlen(buff2), 0);
nsize = recv(my_sock, &buff[0], sizeof(buff) - 1, 0);

// тут парсинг buff[].... //


В итоге данные получаются только первый раз, а все следующие разы nsize=0 :( Что я делаю не так? Как получать строку с сервера максимально быстро? 

Автор: ИванМ 19.10.2009, 21:30
Страницу можно загрузить проще:
Код

string url = "s.test.ru";
WebRequest req = WebRequest.Create(url);
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
StreamReader sr = new StreamReader(stream);
string s = sr.ReadToEnd();

Автор: dobradushny 10.11.2009, 21:14
Мне помогло, спасибо автору....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)