
3 курс (заочка) - Кроссплатформенные технологии программирования / Лабы (выполнить первые 4)
.pdf• Порт: несколькоразныхпрогранаодномсервереогслушать
соединениячерезразныепорты.Каждыйбозначаетсяртномеромв
диапаз1..Н65535омнетдо11024зарезервировара. дляоперационнойы
системы.Убольшинстумолчаниюсервероестьпортв.ДляHTTP |
- |
соединеобычиспользуетсяний80рт.
Программадляз аписи
Нижеуказанытребованияпрограмме,которуювыдолжнынаписать.
1.Программадолжнаприниматьвкоманднойстрокедвараметра:
1)Строку,котораяпредставляетсобойURL |
-адрес,которогоможн |
|
|
начатьпросмотрстраницы. |
|
|
|
2)Положцелоечи, слотельное |
котороеявляетсямаксимальнойглубиной |
|
|
поискасм(.ниже) |
|
|
|
Еслиуказанынекоргумерект,проградолжнанеыетыммаедленно |
|
|
|
остановитьсявыдатьсообщениеиспользуемыхаргументах,например: |
|
|
|
usage: java Crawler <URL><depth> |
|
||
2. |
ПрограммадолжхраURнить |
L-адресввидестрокивместеего |
|
глубикоторая( дляначалаойбудетравна0)Вамбудетнеобходимо. создать |
|
|
|
классдляпредставленияпар[URL, depth]. |
|
|
|
3. |
ПрограммадолжнаподкуказлючисайвURLнномуться |
|
-адресе |
напортс80использованиемсокетасм.( |
н)изапроситьжеуказаннуювеб |
- |
|
страницу. |
|
|
|
4.Программадолжнапроанализироватьвозвращаемыйтекст,
построчнодлюбыхяподстр,имеющихформат: к |
|
|
|
<a href="[любой_URL-адрес_начинающийся_с_http://]"> |
|
||
НайденныеURL |
-адресадолжныбытьсохрновымнывпсаре |
|
|
значениемглубиныв LinkedListподробнееLinkedListsсм(URL,. depth) ( |
|
||
ниже)Новое. значенглубдолжнобытьибольшены,чемзначенглубиены |
|
||
URL-адреса,соответствующегоанализируемстранице. й |
|
||
5. |
Далеепрогрдолжназ крытьсоединениеммасокетахостом |
. |
6.Программадолжнаповторятьшс 3гидля6каждогонового
URL-адреса, гл,убинасоответствующаяURL |
-адр,меньшесу |
||
максимальной.Обратитевниманизвлечении,чтопри поиске |
|
||
определенногоURL |
-адресаглубпоувеличиваетсяскананаЕс1.глуби |
ина |
|
URL-адресадостигаетм ксимальнойглуили(больше),извлы екайте |
|
||
ищитеэтувеб |
-страницу. |
|
|
7. |
Наконец,программадолжнавывестивсепосещенныеURL |
- |
страницывместеихглубпо.инойска
Предположения
• |
Сложноразо,темболееподключитьсярать |
ковсемправильно |
неправильносформированнымгиперссылкамИнтернете.Предположим,что
каждаяссылкасформировахостаправи,поименемлнымьно,путем
ресурсу.Выможетесоздатьнебольшойсайтдлятестир,иливымованияжете
выбратьлюбойдругойса |
|
йтвинтернетесуровнемдоступаhttp://Выожете. ( |
|
попробоватьhttp://slashdotилиhttp://www.org/.nytimes.com.) |
|
||
Вслучае,есливынайдетеURL |
-адрес |
отличным отhttp://методом |
|
доступа,выдолжегоигн.ыорировать |
|
||
• |
Предположим,есливашBufferedReader |
возвращаетзначениеnull, |
|
тосерверзавершилотправкувеб |
-страницы.Наделемомэтовсегдаверно |
|
|
длямедленныхвеб |
-серверов,нодлятекущихцелейэтоприемлемо. |
|
|
Полезныеклассыиметоды |
|
|
|
Указанныенижеклассыметодыдолжпомовамныработуч.ать |
|
||
Обратитевнимание,чтольшинствоэтихметодоввыбрасываютразличные |
|
||
видысключен,котовамприымирабдетсяй.Болееподробнуютать |
|
||
информацвыможесайтенай Javaию API. |
|
||
Socket |
|
|
|
Дляиспользованиясокетов(Socket)вамнеобходимовключитьэтустр |
оку |
||
ввашупрограмму: |
|
|
|
import java.net. *; |
|
Конструктор
Socket создает(Stringновыйсокетизполученнойhost,строкиint port)
именемхостаизцелогочисланомепо,иустанавливаетромсоединение.
Методы
• |
void setSoTimeout(intустанавливаетtimeout) |
времяожиданиясокета |
|
(Socket)вмиллис.Даненкундахтеобходимоыйвызватьпослесоздания |
|
||
сокета,чтобыонзнал,скольконужнождатьпереданныхс ачиругой |
|
||
стороны.Впротивнслучаенегбудетбескомвремяонечноежидания,что |
|
||
приведеткнеэффекти |
вностиразрабск.атывнераемого |
|
•InputStreamвозвращаетInputStream,getInputStream()связанный
SocketЭтотмепозволяетсокету.одполданныесдругойчатьстороны
соединения. |
|
|
|
• |
OutputStreamвозвращаетgetOutputStream() |
OutputStream,связанный |
|
сSocketЭ . тотметодпозвсокетутправлятьляетданадругуюныесторону |
|
|
|
соединения. |
|
|
|
• |
voidзакрываетclose()сокет |
Socket). |
|
Потоки(Streams) |
|
|
|
Дляиспользовпотоковразрабатываемойпрограммениянеобходимо |
|
|
|
включикодследующуюстроку:ь |
|
|
|
import java.io. *; |
|
|
|
Дляэффе ктивнспсокетгользования,вамне преобразоватьбходимо |
|
||
InputStreamи OutputсвязанныеSвоtream,ocket,что |
|
-тоболееудобноев |
|
использовании.ОбъектыInputSOuявляютсяtputStreamпримитивными, |
|
|
|
таккаконимогутчитатьтолькобайтыилимассив |
|
ыбайтов.Поскольку |
|
данработенойеобходчитатьписатьим,выдолжныволыиспользовать |
|
|
|
объекты,которыепреобразуютбайтывсимволыпечатаютцелыестроки. Java |
|
|
|
APIделаетэтонесколькимиразнымиспособамидлявводавывода. |
|
|
Потокиввода (Input Streams)
Дляпотоквводавым испожетеклассыьзоватьInputStreamReader
следующимобразом:
InputStreamReader |
in |
= |
new |
InputStreamReader |
(my_socket.getInputStream());
ТеперьinимееттипInputStreamReader,котможетчитатьрыйсимволыиз
сокета(Socket). |
Ноданподходноченьыйудобен,потомучто |
-прежнему |
приходитсяработатьотдельнымисимволамиилима сивами.мволовДля
чтенияцелыхстроквыможетеиспоклBufferedReaderассьзоватьВыможете .
создатьBufferedReaderобъектамитипаInputStreamRe |
ader,азатемвызвать |
методreadLineпредусмотревBufferedReaderДанметодбудетчитатьнный .
целуюстродругконцас гоединения.
Потокивывода(Output |
Streams) |
Потвыводарганизкипроще.Вым создатьжетеваныэкземпляр
PrintWriterнепосредственн оизобъектаOutputStream,з вызватемеготодь printlnдляотправстротекстанадругкиконсоей.цДлядиненияэтого
использследконструкторющий:йте
PrintWriter (OutputStream out, boolean autoFlush)
ПараметрautoFlushуставзначениеовитеtrue .Этоприведеткочищению буферавыводапослек вызоваждогометодаprintln.
Строкметодыве
ПриведнижметодStringбудутннполезныывработе.Смотрите документациюпо API.
•boolean equals (Object anObject)
•String substring (int beginIndex)
•String substring (int beginIndex, int endIndex)
•boolean startsWith (String prefix)
ПРИМЕЧАНИЕ.Неиспользуйтеоператордля==сравнениястрок!
Операторбудетвозвtrue,толькоащаеслидвестрокиявляютсяьоднимтем
жеобъектом.Есливыхотитесравнитьсодержимое |
двухстрок,используйте |
методequals. |
|
Списки(Lists) |
|
Спохожиискинамассивыобъектов,заисключениемтого,чтоони |
|
могутлегкоменятьразмерностьпринеобходимости,внихиспользуются |
|
скобкидляпоискаотдельныхэлемент.Чтобыиспспискильзовать |
,вы |
должнывключитьследующуюстрпрограммыку: |
|
import java.util. *; |
|
Дляхраненпар(URL,используйтеяLinkedList,depth)которыйявляется |
|
реализациейListСоздайтеего.следующимобразом: |
|
LinkedList <URLDepthPair> myList =новый |
LinkedList <URLDepthPair> |
(); |
|
Посмотритев используемыеAPIметодыв различныесках реализациисписков.Вчастности( ,выможезаметить, разныеореализации
Listпредоставляютразныефункции.Именнопоэтрекомендуетсяму
LinkedList,некотизегфункцийобольшепрые одходятдляэтойработы.)
СпециасинтаксисдсозданияльныйLinkedListпродемонстрированный вышеиспользуетподдержкуJavaЭтот1синтаксис.5означаетgenerics,чтовам .
ненужноиспприведениельзоватьтиповдляобъектов,которыевыхраните илиизвлекает еизсписка.
Исключения
Вслучае,есливынайдетеURL |
-адрес, |
который неначинается«http: //», |
выдолжнывыдатьисключениеMalformedURLException,котороеявляется частьюJava API.
Советыпопроектированию
Нижеприведенырекомендациипоразработкевашего |
поискового |
сканера.
ПарыURL -Depth
Какупоминалосьвыше, должнысоздатьспециклассльный |
|
|
|||
URLDepthPair,каждыйэкземпкотороговключатипасебяярп String,е |
|
|
|||
представляющееURL |
|
-адрес,иполетиint,редставляющееглубпо.инуска |
|
||
Увастакжедол |
|
женбытьметодtoString,которыйвыводитсодержимоепары. |
|
||
Этотмеупрощаетвыводрезультатоввеб |
|
-сканирования. |
|
||
ОтдельныеURL |
-адресанеобходиморазбиначас.ЭанализтьотURL |
- |
|||
адресаиманипуляцияимдолжныбытьчастьюсозданноговамикласса |
|
|
|||
URLDepthPairПравила. хорошегообъектно |
|
-ориентированного |
|||
программиргласят,чтоесликакойвания |
|
-либокласебехранитв |
|
||
опретипданныхеленный,тогдалюбыевидыманипуляцийсэтимиданными |
|
|
|||
такжедолжныбытьреализованыданномклас.Итак, сп какишете |
|
- |
|||
либофункциидлятого,чтобыразбитьURL |
|
|
-адрес,илидляпроверкинато, |
|
|
являетсяиURL |
|
-адресдопустимым,поместитеихвэтоткласс. |
|
||
Сканеры(Crawlers) |
|
|
|
||
Какужеупоминалосьвыше, должныспроектироватьклассCrawler, |
|
|
|||
которыйбудетреализовыватьосновныеф |
|
ункциональвозможностиые |
|||
приложения.ЭтотклассдолжметодньgetSites,которыйбудет |
|
|
|
||
возвращатьсписоквсехпарURL |
|
|
-глубины,которыебылипос.Выщены |
|
|
можвызватьегоосновномтеметодепослезавсканированияршения; |
|
|
|||
получитьсписок,затемвыполни |
|
|
тьитерациюпонемураспечататьвсеURL |
- |
|
адреса. |
|
|
|
|
|
Самыйпростойспособотслеживапосещенныхсайтовсостоиттом,ия |
|
|
|||
чтобыхранитьдвасписка,одвинляехайтов,рассмотренныхдотекущего |
|
|
|||
моменвключает,иодин,ко орыйтольконеобработанныесайты.Ва |
|
мследует |
|||
перебиратьвсайты,которыенебылиобработ,удаляякаждсизныйтй |
|
|
|||
спискапередзагрузкойегос дер,икаждыйраз,когдаимоговынаходите |
|
|
|||
новыйURL |
-адрес,необходимопоместитьеговнеобработанныйсписок.Когда |
|
|||
необрабосписокпус, танный |
|
|
канерзавершаетработу. |
|
Несмотрянато,чтов зникаетпредп,чтооткрытиелс пожениекета |
|
|
|
|
URL-адресу - операция,связаннаяURL |
-адресом,и,следовательно,должна |
|||
бытьреализованаклассепарURL |
|
-Depth,этобылослишком |
|
|
специадляцелейкизированным |
ласса.Клп URLсср |
-Depthявляетсятолько |
||
местомдляхраненияURL |
-адресовизначенглуб,такжевключаетийны |
|
|
|
себянесколькодополнительныхутилит.Сканер(Crawler) |
|
|
- этокласс,который |
|
перемещаетсяповеб |
-страницамищетURL |
-адреса,поэтомукласс |
сканера |
|
долженвключасебякод, факторыйьоткрываетическизакрывает |
|
|
|
|
сокеты. |
|
|
|
|
ВамнужсоздатьновыйэкземплярSocketдлякаждогоURL |
|
|
-адреса, |
|
котороговызагружаететекст.Обязательнозакройсоке,когдавызакончите |
|
|
|
|
сканированиеэтойвеб |
-страницы,чтобыоперационнаясистеманеисчерпала |
|
|
|
сетре.выесурсыКо( мпьюдержатьожеоткрытымиочемнс ькетовго |
|
|
|
|
одновре)Кро. т,неиспользуйтегом ннорекурсиюдляпоискаглубоко |
|
|
|
|
вложенныхвеб |
-ст;раницеализуйтеэтуфункциючерезцикл.Этотакже |
|
|
|
сделаетвашвеб |
-сканерболееэффектсточкизренияспользованиявным |
|
|
|
ресурсов. |
|
|
|
|
Константы |
|
|
|
|
Разрабатываемаяпрограммабудетсодесттипажатьоки«http:«a //» |
|
|
|
|
href = \»,иувасможетвозникнуиспользжеланиеэстрокивезде,гдевать |
|
|
|
|
ониваммогутпонадоб |
иться.Кр,оваммегопонадлиныразныхобятсяля |
|
|
|
строковыхопераций,поэувасакжеомуможетвозникнутьжеланиежестко |
|
|
|
|
закоддлэтихстррованык.Несдектэтоьоитделать.Есливысделаете |
|
|
|
|
опечаткуилипозжепоменяетеспособпоиска,вампридется |
|
|
соответственно |
|
поменятьдостатоколистроккодач.ноеество |
|
|
|
|
Вместоэтогсоздайтестроковыеконсткл.Напримерссахнты |
|
|
: |
|
public static final string URL_PREFIX = "http: //"; |
|
|

Теперь,есливамбудетнужнаэтастрока,используйтеконстанту |
|
||
URLЕсливPREFIX. |
амнужнаеедлина,используйтестроковыйметоддля |
|
|
приведеннойвышеконстанты: URL PREFIX.length(). |
|
||
Продумайтераспк ложение.нстантВамобходимо,ч каждаяобы |
|
||
константапоявляласьодинразвовсемпроекте,ивыдолжныразместить |
|
||
константутам,гдеэто |
|
наиболеецелесообразно.На,посколькуримпр фикс |
|
URL-адресанужендлятого,чтобыпределить,действителенURL |
-адрес,вы |
||
должныпоместиэтуконсвкласстURLьнту |
|
-DepthЕслиувасеещеодна.ть |
|
кондляссылтантаHTML,помкевклассе титеканер |
|
а.Еусканерали |
|
появитсянеобходимостьпрефикURL,онможетылатьсянаконстанту |
|
||
парыURL |
-depth,вместодублированияэтк йнстанты. |
|
Дополнительноезадание
•Добавьтекоддлядобасайтвнеленияовбработанныйсписок,если
онбылиепросмотреныран |
ее. |
• Расширьтевозмппожностигиперсскусканера, пользуяылок поискрегулярнымвыражениямсобранныхданных.Ватакже понадбольшетсялог,чтобыирки,шитькакоймашинеподключатьсяв
следующейитерации.Сканердолжениметьвозможностьперем ещатьсяпо ссылкамнаразличныхпопулярныхсайтах.
•Создайтепулизпятиилиболее( )сканеров.Каждыйдолжен
работавсвоемпо,каждыйтьокеможетполучитьURL |
-адресдляпросмотраи |
|
кажизнихдолженыйвернутьсписссылокпозавершениюработы. |
||
Посылайте новыеURL |
-адресавэтотпул,к олькоонистанутдоступными. |
|
• |
Расширьсканермногопоттак,чтоможнобычныйл |
выпонаглубинулнитьискдо1 Сохраняй000резуль000каждого. татые обходавбазеданныхчерезJDBCизапишите,сколькоразнакаждую конкретнуюуникальнуюстраницуссылалдруг.Включитесь интелалгоритмектуальныйдляпоис«смысла»накастраницеждойпутем взвешивасловфрносновеповторяемостиия,близостикначалуабзацев
разделов,размерашрифтаилистилязаголовка,покр |
айнеймере,мета |
- |
ключеслов. ых

Лабораторнаяработа№8: |
|
Модифицированный веб-сканер |
|||
Сканервпрошлойлабораторнойраббылнетесобенноэффективным.В |
|
|
|
||
даннойлабораторнойработевырасшсканердляиспользованияритепоточной |
|
|
|
|
|
обработкиJavaтак,чтобынес |
|
кольковеб |
-страницможнобылсканировать |
||
параллельно.Этоприведеткзначительномуповышениюпроизводительности, |
|
|
|
||
таккаквремя,которсканеракаждыйпотоктратитнаожиданиезавершения |
|
|
|
|
|
сетевыхопераций,можпр другимирыватьсяоперациямиобработкид |
|
|
|
ругих |
|
потоках. |
|
|
|
|
|
ПодробноевведениямногопоточноепрогрнаJavaммированиевы |
|
|
|
||
можетепрочитатьвданном |
|
учебнруководствем |
.Самоеглавноепрочитать |
||
этот подраздел. |
|
|
|
|
|
Расширениевеб |
-сканера |
|
|
|
|
Вданнойлабораторнойработевырасширитеизменитеразработанную |
|
|
|
||
ранеепрограмму: |
|
|
|
|
|
1Реал. классизуйтеменемURLPool,котобудетхранитьый |
|
|
|
список |
|
всехURL -адресовдляпоистакже, относительныйуровень" "каждогоиз |
|
|
|
||
этихURL -адресовтакже( извкакглуб"стныйпо")Первыйи.сканаURL |
|
|
|
-адрес, |
|
которыйнужнобудетнайти,будетиметьглубравнуюпоиска0, URL |
|
|
|
- |
|
адреса,найденныеэтойстраниц |
|
е,будутиметьглубравнуюпоискаи1 |
|
|
|
т.д.НеобсоходиморанитьURL |
|
-адресаиихглубповместеи,сканукак |
|
|
|
экземплярыклассаименемURLDepthPair,какэтобылосделановпрошлой |
|
|
|
|
|
лабораторнработе. LinkedListкиспоймендуетсяхраненияльзовать |
|
|
|
|
|
элемен,таккакэтоп эффективможетвыполнеобходимыеоперациинить. |
|
|
|
|
|
УпользователяклассаURLPoolдолженбытьспособполученияпары |
|
|
|
|
|
URL-глубинаизпулаудэтойленияпарыизспискаодноврем.Долженно |
|
|
|
||
такжебытьспособдобавленияпарыURL |
|
|
-глубинак |
пулу.Обеэтиоперации |
|
должныбытьпоточно |
-ориентир,таккакнесколькопотоковбудутваны |
|
|
|
|
взаимодейстURLPoolодновременно. овать |
|
|
|
|
|