Въведение в WinNet
Само вчера дори не си помислихте да пишете програми, които използват интернет протоколи, вярвайки, че това е многото на уеб програмистите. Но вече днес вие сте изправени пред задачата да четете / пишете, предавате / получавате, получавате / изпращате нещо от вашата програма до всеки интернет сървър. Какви средства съществуват за това? Колко време ще отнеме изучаването и експериментирането? Нека да разгледаме един от начините, който ви позволява да разрешите повечето от тези проблеми в най-кратки срокове.
Win32 Internet Extensions или WinInet е API за достъп до общи интернет протоколи, включително FTP, HTTP и Gopher. Това е API на високо ниво, който позволява, за разлика от WinSock или TCP / IP, да не се притеснявате за подробностите за изпълнение на съответните интернет протоколи. Като цяло API съдържа малко по-малко от сто функции за всички случаи, но не ни трябват повече от дузина, за да започнем с WinInet.
Необходим минимум
WinInet API функции
Нека анализираме всички функции по ред и да разгледаме само тези параметри, които ще ни трябват.
Интернет отворен
Тази функция инициализира WinInet и връща манипулатор, който е необходим за извикване на други функции на WinInet. При повреда се връща NULL. По-подробна информация за грешки може да бъде получена чрез извикване на функцията GetLastError, която връща един от кодовете, дефинирани във файла wininet.h.
lpszAgent | Указва името на приложението, което се използва като агент в HTTP протокола. Сървърът може да дефинира агент, като използва сървърната променлива HTTP_USER_AGENT. Ако вашата програма ще имитира MS Internet Explorer, подайте низа "Mozilla/4.0 (съвместим; MSIE 6.0b; Windows NT 5.0; .NET CLR 1.0.2914)" към този параметър |
dwAccessType | Указва необходимия тип достъп (директен или чрез прокси). Ще използваме стойността INTERNET_OPEN_TYPE_PRECONFIG, която задава вида на достъп според настройките в системния регистър. |
Интернет връзка
Тази функция отваря FTP, HTTP или Gopher сесия за дадения сайт.
HttpOpenRequest
HTTP заявката се изпълнява на няколко етапа: отваряне на заявка, определяне на HTTP заглавката, действително изпращане на заявката, четене и обработка на данни. Тази функция, както подсказва името й, отваря HTTP заявка.
HttpSendRequest
Изпраща заявка до сървъра.
InternetReadFile
InternetCloseHandle
Тази функция затваря всеки манипулатор, създаден от предишните функции.
hИнтернет | Манипулатор, получен чрез извикване на функциите InternetOpen, InternetConnect или HttpOpenRequest. |
Четене на страницата
Сега знаем всичко необходимо, за да напишем прост HTML четец. Нашият пример може да изглежда така:
Както можете да видите, всичко е съвсем просто, въпреки че този пример може да бъде направен още по-прост. Това е така, защото WinInet включва функция InternetOpenUrl, която може да замени двойката HttpOpenRequest и HttpSendRequest. Но лесните начини не са за нас, особено след като не се интересуваме само от четене на страници, а от пълна комуникация със сървъра.
Какво ни трябва за това?
Да започнем с това.
Клас CHTTPReader
MFC съдържа цял набор от класове, които ви позволяват да работите с WinInet, защо се нуждаем от друг клас? Първо, MFC класовете са обвивки за API функции, така че нашият пример няма да изглежда много по-прост. Ще трябва да създадем няколко обекта, все още да помним всички необходими флагове и често да разглеждамеMSDN. От друга страна, нашият клас няма да е универсален, той ще работи само с HTTP протокола и ще има минимално необходимия набор от функции. Но ще бъде просто и лесно за използване. Второ, MFC си е MFC, ако не искаме да използваме MFC, тогава ще бъдем принудени да използваме API или. напиши класа си :o)
Декларация на клас
Ето интерфейса на класа CHTTPReader:
Маркирани са функциите, които ще използваме постоянно. Останалите могат да бъдат полезни, но не е нужно да ги използвате. По-долу е дадено описание на методите на класа CHTTPReader.
CHTTPReader
OpenInternet, OpenConnection
Извиква се автоматично при поискване. Първата функция инициализира WinInet и може да се използва за указване на име на приложение. Вторият отваря HTTP сесия и ви позволява да посочите името на сървъра.
lpszAgent | Указва името на приложението, което се използва като агент в HTTP протокола. Сървърът може да дефинира агент, като използва сървърната променлива HTTP_USER_AGENT. |
lpszИме на сървъра | Указва името на сървъра. Ако този параметър не е зададен и името на сървъра не е зададено в конструктора, тогава "localhost" се използва като име на сървъра. |
Изпратете заявка до сървъра до сървъра, като използвате метода "GET" или "POST".
Чете данни от сървъра.
Втората версия на функцията чете данни във вътрешен буфер, чийто размер се определя чрез извикване на GetDataSize. NULL се връща при грешка или завършване на четене на данни.
GetDataSize
Връща размера на данните, налични за четене.
Използва функцията HttpQueryInfo с параметъра HTTP_QUERY_CONTENT_LENGTH за получаване на информация. Срещнах ситуация, когато тази функция върна нула, въпреки че след това данните бяха прочетени изцялосила на звука. Би било възможно да се използва функцията InternetQueryDataAvailable, но тя също не е наред. Например, при четене на ASP страница, тази функция не връща размера на получената страница, а размера на самия скрипт, което несъмнено е много интересна информация, но напълно безполезна за нас. В резултат на това не знам и не мога да ви предложа абсолютно надежден начин да получите точна информация за размера на исканите данни. Това най-вероятно ще работи, но ако възнамерявате да използвате сървъри, които не можете да тествате предварително, най-добре е да не разчитате на тези функции.
SetDataBuffer
Задава размера на вътрешния буфер.
dwBufferSize | Новият размер на буфера. |
CloseRequest, CloseConnection, CloseInternet
Извиква се автоматично при нужда. Освободете подходящите ресурси.
SetDefaultHeader
Позволява ви да зададете HTTP заглавки.
lpszHeader по подразбиране | Съдържание на заглавката. |
Връща кода GetLastError за последното неуспешно извикване на функция WinInet.
Четене на страницата отново
Този път ще използваме класа CHTTPReader, за да четем същата страница с новини. Ето какво излезе от това:
Маркираните редове всъщност са това, което се отнася до заявката, останалото е имитация на енергична дейност. Както можете да видите сега, всичко е съвсем просто.
Комуникация със сървъра
Четене на обменния курс
Нека направим нещо по-полезно от простото четене на страниците с новини. Например, колкото и да е странно, вече разполагаме с всички средства за четене на данни за обменните курсове към дадена дата от сървъра на Централната банка на Руската федерация. Следващият пример демонстрира тази възможност.
Всъщност ние образуваме низзаявка, която в браузъра изглежда така "http://www.cbr.ru/currency_base/D_print.asp?date_req=DD.MM.YYYY" , където трябва да замените необходимата дата вместо ДД, ММ, ГГГГ. След това изпращаме заявка до сървъра и анализираме резултата, извличайки необходимата информация. Този пример работи чудесно, но има един съществен недостатък - зависи от структурата на HTML документа, която може да бъде променяна по всяко време от CBR програмистите.
Клиентски сървър
Сега е време да насочим вниманието си към разработването на цялостно клиент-сървър приложение. Какво ще направи не е толкова важно, по-важно е как ще го направи. Ето защо, като пример, нека вземем прост калкулатор или по-скоро дори множител. Ето текста на ASP скрипта на нашата сървърна страна на приложението:
Всичко, от което се нуждаем, за да работим, е подчертаният фрагмент, останалата част от текста е само за демонстрационни цели. Можете да стартирате този скрипт и да видите дали работи. Кликнете върху следната връзка: calc.asp.
Сега нека да разгледаме клиентската страна на нашето приложение. Данните се прехвърлят към сървъра чрез метода "PUT" или "POST". Вече имаме функция Post, която може да свърши цялата необходима работа. Ако забележите, изборът на текст в calc.asp изглежда необичаен за ASP скрипт. Точно така, нашият скрипт връща данни в XML формат. И къде сега без него? :o) Нашият клиент ще получи резултата в XML формат и ще използва MSXML анализатора, за да обработи резултата:
Пуснете този пример и вижте дали работи. Имайте предвид, че цялата тежка работа по умножаването на две числа се извършва от RSDN.ru ;o) Разбира се, този метод не е най-бързият, но въпреки това, ако имате проблеми с умножението, тогававинаги си добре дошъл!
Помощни средства
За да отстраним грешки в нашите заявки, първо се нуждаем от интернет сървър. Windows 2000 идва с IIS 5.0, което е добре за нас, въпреки че можете да използвате всеки друг. Много HTML формуляри, в допълнение към видимите полета за въвеждане, съдържат скрити полета, които често са размазани в целия HTML документ. Намирането на тези полета не е лесна задача, особено ако документът е създаден програмно и програмистът не трябва да се грижи за неговата четливост. Следният скрипт ще ни помогне да се справим с този проблем:
За да тестваме нашия скрипт в действие, нека направим следното:
Браузърът отново ще покаже var.asp, но този път първата таблица ще бъде попълнена с имената на полетата и стойностите на формуляра за въвеждане на предишната страница, т.е. Трябва да получите нещо подобно:
Променлива на формуляра | Стойност |
Твърд | 123 |
урбанизация | |
адрес за доставка | 123 |
град | 123 |
Изпращане | процес |
състояние | 12 |
Пощенски код | 123 |
Сега имаме пълна картина, включително имената на редовните и скритите полета и техните стойности.
Къде е тази улица, къде е тази къща? >8(
Нека използваме получената информация, за да отговорим на този любопитен въпрос.
Коментарите отбелязват места, които трябва да разгледаме, за да разберем какво се случва.
Заключение
Независимо от това, WinInet е много подходящ за прости и средно сложни задачи. Ако трябва да добавите към програмата, например, възможността за онлайн регистрация, тогава, надявам се, сега ще трябва да напишете най-комуникациятачасти не повече от половин час. Четенето на WWW-страници, както можете да видите, също не е трудно. Всъщност можете програмно да правите всичко, което можете да правите в браузър, включително процеса на влизане с парола. Но ако решите да напишете самия браузър. тогава, очевидно, гнездата са по-подходящи за това.