wxHTTP не работает Topic is solved

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
Post Reply
Dok
In need of some credit
In need of some credit
Posts: 9
Joined: Sun Aug 01, 2010 7:30 pm
Location: Russia, Samara
Contact:

wxHTTP не работает

Post by Dok »

Почему-то не хочет работать стандартнейший код примера для wxHTTP:

Code: Select all

wxHTTP get;
get.SetHeader(_T("Content-type"), _T("text/html; charset=utf-8"));
get.SetTimeout(10); // 10 seconds of timeout instead of 10 minutes ...
 
// this will wait until the user connects to the internet. It is important in case of dialup (or ADSL) connections
while (!get.Connect(_T("www.google.com")))  // only the server, no pages here yet ...
    wxSleep(5);
 
wxApp::IsMainLoopRunning(); // should return true
 
// use _T("/") for index.html, index.php, default.asp, etc.
wxInputStream *httpStream = get.GetInputStream(_T("/intl/en/about.html"));
 
// wxLogVerbose( wxString(_T(" GetInputStream: ")) << get.GetResponse() << _T("-") << ((resStream)? _T("OK ") : _T("FAILURE ")) << get.GetError() );
 
if (get.GetError() == wxPROTO_NOERR)
{
    wxString res;
    wxStringOutputStream out_stream(&res);
    httpStream->Read(out_stream);
 
    wxMessageBox(res);
    // wxLogVerbose( wxString(_T(" returned document length: ")) << res.Length() );
}
else
{
    wxMessageBox(_T("Unable to connect!"));
}
 
wxDELETE(httpStream);
get.Close();
Программа, как показала практика, навечно зацикливается в следующем месте:

Code: Select all

while (!get.Connect(_T("www.google.com")))  // only the server, no pages here yet ...
    wxSleep(5);
Что любопытно, если вместо строки использовать ip-адрес, например, 271.0.0.1 то программа из зацикливания благополучно выходит, но с сервером все равно не соединяется (проверено командой get.IsConnected()). Что делать? Может быть, для обмена информацией с сервером более подходит какой-либо другой компонент из арсенала wxWidgets?
Debes ergo potes (lat.)
-------------------------------------
OS: Windows 7 / Ubuntu 10.04
Compiler: Code::Blocks NB
wxWidgets: 2.8.10
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

Попробуй в OnInit() класса приложения добавить

Code: Select all

wxSocketBase::Initialize();
Dok
In need of some credit
In need of some credit
Posts: 9
Joined: Sun Aug 01, 2010 7:30 pm
Location: Russia, Samara
Contact:

Post by Dok »

Бесполезно. Может я что-то не туда добавил?

Code: Select all


bool wxWidgetsApp::OnInit()
{
wxSocketBase::Initialize();

wxHTTP get;
get.SetHeader(_T("Content-type"), _T("text/html; charset=utf-8"));
get.SetTimeout(10); // 10 seconds of timeout instead of 10 minutes ...

// this will wait until the user connects to the internet. It is important in case of dialup (or ADSL) connections
while (!get.Connect(_T("www.google.com")))  // only the server, no pages here yet ...
    wxSleep(5);

wxApp::IsMainLoopRunning(); // should return true

// use _T("/") for index.html, index.php, default.asp, etc.
wxInputStream *httpStream = get.GetInputStream(_T("/"));

// wxLogVerbose( wxString(_T(" GetInputStream: ")) << get.GetResponse() << _T("-") << ((resStream)? _T("OK ") : _T("FAILURE ")) << get.GetError() );

if (get.GetError() == wxPROTO_NOERR)
{
    wxString res;
    wxStringOutputStream out_stream(&res);
    httpStream->Read(out_stream);

    wxMessageBox(res);
    // wxLogVerbose( wxString(_T(" returned document length: ")) << res.Length() );
}
else
{
    wxMessageBox(_T("Unable to connect!"));
}

wxDELETE(httpStream);
get.Close();

    gfru_rbmainWin* frm = new gfru_rbmainWin( (wxWindow*)NULL );
    frm->Show();
    return true;
}
Debes ergo potes (lat.)
-------------------------------------
OS: Windows 7 / Ubuntu 10.04
Compiler: Code::Blocks NB
wxWidgets: 2.8.10
midisa
Earned some good credits
Earned some good credits
Posts: 113
Joined: Tue Jun 22, 2010 4:15 pm
Contact:

Post by midisa »

Dok wrote:Бесполезно. Может я что-то не туда добавил?

Code: Select all


bool wxWidgetsApp::OnInit()
{
wxSocketBase::Initialize();

wxHTTP get;
get.SetHeader(_T("Content-type"), _T("text/html; charset=utf-8"));
get.SetTimeout(10); // 10 seconds of timeout instead of 10 minutes ...

// this will wait until the user connects to the internet. It is important in case of dialup (or ADSL) connections
while (!get.Connect(_T("www.google.com")))  // only the server, no pages here yet ...
    wxSleep(5);

wxApp::IsMainLoopRunning(); // should return true

// use _T("/") for index.html, index.php, default.asp, etc.
wxInputStream *httpStream = get.GetInputStream(_T("/"));

// wxLogVerbose( wxString(_T(" GetInputStream: ")) << get.GetResponse() << _T("-") << ((resStream)? _T("OK ") : _T("FAILURE ")) << get.GetError() );

if (get.GetError() == wxPROTO_NOERR)
{
    wxString res;
    wxStringOutputStream out_stream(&res);
    httpStream->Read(out_stream);

    wxMessageBox(res);
    // wxLogVerbose( wxString(_T(" returned document length: ")) << res.Length() );
}
else
{
    wxMessageBox(_T("Unable to connect!"));
}

wxDELETE(httpStream);
get.Close();

    gfru_rbmainWin* frm = new gfru_rbmainWin( (wxWindow*)NULL );
    frm->Show();
    return true;
}
Я конечно не специалист, но у вас так все мутно в коде ... постараюсь развеять, на сколько я это все понимаю.
Просто скажу свое мнение, а вы его проверите.
1. Инициализация вообще должна проходить внутри класса при вызове... хотя в данной ситуации ...
2. Я бы стал так писать:
wxHTTP get;
что то вернет = get.Connect(_T("www.google.com"); // как я понимаю он сам будет в режиме ожидания пока не откроет страницу. Это не Windows API здесь не надо перебирать строки. Хотя я не уверен. Как я понимаю, wxWidget это "командный интерпретатор", обертка на обертке. Здесь должно быть все максимально просто как велосипед.
То что вернет, смотри и проверяй. Если получил то что ожидал, значит соединились, если нет, то не судьба.
ГЛАВНОЕ не забудь добавить http:// впереди т.к. эта ... не будет знать по какому протоколу запрашивать. Возможно что она понятия не имеет какой механизм задействовать при открытии страницы.
get.Close(); // в конце нужно закрыть.

Остальное бы я удалил. На мой взгляд остальное все лишнее, если вы хотите только проверить подключение.
Это просто мое мнение, не более того. Возможно что я не прав т.к. сам делаю первые шаги в программировании с wxWidget под Linux.
Dok
In need of some credit
In need of some credit
Posts: 9
Joined: Sun Aug 01, 2010 7:30 pm
Location: Russia, Samara
Contact:

Post by Dok »

Я конечно не специалист, но у вас так все мутно в коде ... постараюсь развеять, на сколько я это все понимаю.
Просто скажу свое мнение, а вы его проверите.
1. Инициализация вообще должна проходить внутри класса при вызове... хотя в данной ситуации ...
2. Я бы стал так писать:
wxHTTP get;
что то вернет = get.Connect(_T("www.google.com"); // как я понимаю он сам будет в режиме ожидания пока не откроет страницу. Это не Windows API здесь не надо перебирать строки. Хотя я не уверен. Как я понимаю, wxWidget это "командный интерпретатор", обертка на обертке. Здесь должно быть все максимально просто как велосипед.
То что вернет, смотри и проверяй. Если получил то что ожидал, значит соединились, если нет, то не судьба.
ГЛАВНОЕ не забудь добавить http:// впереди т.к. эта ... не будет знать по какому протоколу запрашивать. Возможно что она понятия не имеет какой механизм задействовать при открытии страницы.
get.Close(); // в конце нужно закрыть.

Остальное бы я удалил. На мой взгляд остальное все лишнее, если вы хотите только проверить подключение.
Это просто мое мнение, не более того. Возможно что я не прав т.к. сам делаю первые шаги в программировании с wxWidget под Linux.
Боюсь, ваше мнение ошибочно) Дело в том, что функция get.Connect() возвращает значение типа bool, так что ничего кроме обычной проверки не сделаешь. Тем более, что в документации wxWidgets написано, что эта функция не соединяется сама по себе с сервером, а просто сообщает его имя объекту.
Я компилировал это на Windows 7 и XP, думаю вот все же попробовать на Linux`е собрать, хотя помочь не должно. =)
А код этот взят с официального wiki wxWidgets по wxHttp, то есть он "как бы" ДОЛЖЕН работать.

Может быть, кто-нибудь кто работал с сетью через wxWidgets, расскажет каким способом он пользовался? Насколько я знаю, библиотека wxNet обширна в классах, правда использование их довольно туманно.
Debes ergo potes (lat.)
-------------------------------------
OS: Windows 7 / Ubuntu 10.04
Compiler: Code::Blocks NB
wxWidgets: 2.8.10
private_joker
Earned a small fee
Earned a small fee
Posts: 12
Joined: Tue Nov 24, 2009 6:26 pm

Post by private_joker »

С разной степенью вероятности:
- Если приложение не консольное, убрать все кроме инициализации сокетов из OnInit(). Остальное выделить в отдельный метод.
- Если консольное, попробовать тот же код в Gui-приложении.
- httpStream надо проверять на NULL (в том же условии где ты проверяешь HTTP на ошибку протокола).
- Не вижу как ты формируешь GET-запрос, дефолтный вполне мог быть послан сервером "лесом". Use sniffer, Luke. (Smart Sniff, Wireshark, etc.)

Личное наблюдение (можешь внять, можешь нет, я провел за "допиливанием" этого ужоса пару месяцев):
- wxHTTP довольно бажен.
- wxHTTP обеспечивает базовую helloworld функциональность, ВСЕ(ответы, редиректы, потоки) надо дописывать руками. Причем просто так отсабклассится и получть доступ ко всему и вся проблематично.
В общем масса увлекательных проблем обеспечена. Поэтому я перевел все что нужно на wxCurl (обертка над pure-C CURL) и советую поступить также.
Dok
In need of some credit
In need of some credit
Posts: 9
Joined: Sun Aug 01, 2010 7:30 pm
Location: Russia, Samara
Contact:

Post by Dok »

private_joker wrote:С разной степенью вероятности:
- Если приложение не консольное, убрать все кроме инициализации сокетов из OnInit(). Остальное выделить в отдельный метод.
- Если консольное, попробовать тот же код в Gui-приложении.
- httpStream надо проверять на NULL (в том же условии где ты проверяешь HTTP на ошибку протокола).
- Не вижу как ты формируешь GET-запрос, дефолтный вполне мог быть послан сервером "лесом". Use sniffer, Luke. (Smart Sniff, Wireshark, etc.)

Личное наблюдение (можешь внять, можешь нет, я провел за "допиливанием" этого ужоса пару месяцев):
- wxHTTP довольно бажен.
- wxHTTP обеспечивает базовую helloworld функциональность, ВСЕ(ответы, редиректы, потоки) надо дописывать руками. Причем просто так отсабклассится и получть доступ ко всему и вся проблематично.
В общем масса увлекательных проблем обеспечена. Поэтому я перевел все что нужно на wxCurl (обертка над pure-C CURL) и советую поступить также.
Спасибо за ответ, действительно надо посмотреть этот wxCurl. Работать напильником, безусловно, полезно для общего развития, но слишком накладно. =)
Debes ergo potes (lat.)
-------------------------------------
OS: Windows 7 / Ubuntu 10.04
Compiler: Code::Blocks NB
wxWidgets: 2.8.10
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

Кроме google.com что-то прбовали? Google вроде редиректит сразу на локальный сайт по IP. Я думаю надо еще код возврата проверить, а то там скорее всего пустой контент и 302й редирект стоит. попробуйте другой сайт какой-нибудь (не Яндекс, он тоже редиректит вроде)
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

А, и да, еще.. Если надо просто сграбить страничку, то проще wxURL юзать.
User avatar
T-Rex
Moderator
Moderator
Posts: 1248
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Post by T-Rex »

С моей стороны пакеты ушли (с)
В общем, вроде рабоатет

Code: Select all

#include <wx/wx.h>
#include <wx/socket.h>
#include <wx/sstream.h>
#include <wx/protocol/http.h>

class wxTestApp : public wxApp
{
public:
	virtual bool OnInit()
	{
		wxSocketBase::Initialize();
		wxHTTP http;
		for(size_t i = 0; i < 15; i++)
		{
			if(!http.Connect(wxT("wxwidgets.org"))) 
			{
				wxSleep(2);
			}
		}
		wxInputStream * stream = http.GetInputStream(wxT("/about/"));
		if((http.GetError() == wxPROTO_NOERR) && stream)
		{
			wxString res;
			wxStringOutputStream out_stream(&res);
			stream->Read(out_stream);
			wxLogDebug(wxT("%s"), res.GetData());
			wxDELETE(stream);
		}
		http.Close();

		return false;
	}
};

IMPLEMENT_APP(wxTestApp)
Post Reply