Главная
Трудоустройство
Ваши объявления
Наши новости
Информация







Hello, Perl! Perl FAQ по-русски

Дмитрий Репин aka cmapuk[0nline]

ЧАСТЬ 7.








Продолжаем практиковаться в программировании на языке Perl. В этой части мы рассмотрим вопросы сетевого программирования, а также узнаем о некоторых полезных модулях.


Сетевые приложения с Net::XXX. Модули класса Net предоставляют возможность работать с различными протоколами прикладного уровня. Это и FTP, и почтовые POP3 и IMAP, и многие другие. Есть также такие возможности, как работа с через proxy. Краткий рассказ о работе с этими модулями и другую документацию можно взять на сайте http://www.pobox.com/~gbarr/libnet/. Вот небольшой обзор семейства Net:

Net::FTP - Работа с FTP
Net::IMAP::Simple - Проверить почту с IMAP-сервера
Net::IRC - Написать клиента для IRC
Net::NNTP - Работа с News протоколом
Net::Ping - Ping, как он есть )
Net::POP3 - Почта POP3
Net::Printer - Печать на принтер
Net::SMTP Отправка писем через SMTP
Net::SMTP::Server - Создание SMTP-сервера
Net::SOCKS - Работа с SOCKS-сервером
Net::SSH - Работа с секьюрным шеллом
Net::Telnet - Телнет
Net::Whois - Поиск доменов через InterNIC
Net::ICQ2000 - Написать свою аську на Perl ;-))

Все семейство этих модулей называется libnet (также как семейство модулей LWP называется libwww-perl), и вы можете использовать это название при поиске информации в поисковых системах. Большинство модулей работают одинаково как под *nix-системы, так и под всеми любимой и ненавидимой Windows.

Проверим почту с сервера www.pisem.net

use Net::IMAP::Simple;
$user="username@pisem.net";
$pass="Мою кошку зовут JHf^!hdg+/"
$server = new Net::IMAP::Simple-(smtp.hotbox.ru); # Подключаемся
$server->login($user,$pass); # Логинимся
$mess_num = $server->select(INBOX); # Выбираем папку INBOX
foreach $msg ( 1..$mess_num ) {
         $lines = $server->get($msg);         # Получаем письмо в виде ссылки на массив строк
         print @{$lines};         # Распечатываем на экран
}
$server->quit();                 # Отключаемся

Примерно таким же образом происходит работа с другими модулями семейства Net

Возможно, вам может понадобиться работать с сетевыми пакетами на низком уровне, например собирать/разбирать UDP-пакеты. Здесь вам понадобятся модули семейства NetPacket. Для каждого протокола нужно подключать модуль NetPacket::ИмяПрото-кола. Например NetPacket::UDP, NetPacket: :Ethernet, NetPacket::TCP и и.п.

# Простейший POP3-сниффер из документации NetPacket::TCP
use Net::PcapUtils; # Модуль для отлова пакетов
use NetPacket::Ethernet qw(:strip);
use NetPacket::IP qw(:strip);
use NetPacket::TCP;
sub process_pkt {
         my($arg, $hdr, $pkt) = @_;
         my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
         if (($tcp_obj->{src_port} == 110) or ($tcp_obj->{dest_port} == 110)) {
print($tcp_obj->{data});
}
}
# Прослушиваем канал на предмет TCP-пакетов.
# Для "пойманного" пакета выполняется proccess_pkt
Net::PcapUtils::loop(\&process_pkt, FILTER => tcp);

Как произвести сжатие данных? Вам поможет модуль Compress::Zlib. Он позволяет не только работать с файлами, но и архивировать/разархивировать данные "на лету".

use Compress::Zlib;
$compressed = compress($source);
$source = uncompress($compressed);

Подробнее обо всех возможностях модуля - в perldoc Compress::Zlib.

Шифрование данных. Вы наверняка интересовались, как шифровать и расшифровывать данные с помощью Perl. Здесь пригодится модуль Crypt::DES или его собратья (Crypt::Blowfish и т.п.).

use Crypt::DES;
$key = pack("H16", "0123456789ABCDEF");
$crypt = new Crypt::DES $key;
$crypted = $cipher->encrypt($mytext);
$mytext = $crypt->decrypt($crypted);

Работа с файлами. Если вы не хотите изобретать механизмы различных манипуляций с файлами, то воспользуйтесь модулями семейства File

File::Compare - Сравнение файлов
File::Find - Поиск файлов
File::Path - Создание/Удаление дерева директорий
File::Spec - Манипуляции именами файлов/директорий
File::stat - Интерфейс к стандартной функции stat()
File::Temp - Работа с временными файлами/директориями
use File::Path;
mkpath($array_of_dirnames_reference, 0, 0755);
rmtree($array_of_dirnames_reference, 1);

Здесь первый парамер - ссылка на массив путей новых директорий. Второй - флажок true/false - сообщать о каждой операции или все делать "молча". Третий параметр у mkpath - права.

Форматы текста. Переводы текста между различными форматами (TXT, POD, RTF, HTML, etc) - дело непростое, и лучше всего доверить его соответствующим модулям. Рассмотрим для начала семейство HTML.

Объекты некоторых из модулей этого семейства интегрируются с LWP-обьектами. Чуть ниже вы это увидите.

HTML::AsSubs - Построение страницы HTML-функциями
HTML::Entities - Кодирование символов типа c ©
HTML::Filter - Фильтр для удаления тегов
HTML::Form - Создание форм
HTML::HeadParser - Разбор блока HEAD
HTML::LinkExtor - Выборка линков из страницы
HTML::Parser - Парсер HTML
HTML::Tree - Создание дерева вложенно-сти тегов
# Выборка формы из страницы и ее последующая отправка
use HTML::Form;
$form = HTML::Form->parse($html_page, $base_uri);
$form->value(query => "Perl");
use LWP;
LWP::UserAgent->new->request($form->click);
...

POD-формат - формат для документации. В комплекте Perl есть утилиты pod2text, pod2html и т.п. для преобразования в более читабельный вид ;-). Кроме того, имеется семейство модулей POD::***, позволяющее работать с этим форматом и преобразовывать его в нормальное для чтения представление.

Для работы с RTF-текстами имеются модули RTF::Document, RTF::HTML::Converter, и т.п.. Правда, эти модули очень плохо относятся к русским буквам и другим чуждым "буржуинским" программерам символам. Но это не беда. Откройте файл модуля RFT::HTML::Converter (и RFT::Text::Converter тоже) и в строке номер 77 сделайте следующую поправку:

"&#$_;" на сhr($_). Иначе все символы, не являющиеся английскими буквами, превратятся в &#[КодASCII].

Очень силен в обращении с текстовыми данными модуль Text (точнее, его семейство). Это даже не модуль, а целый текстовый процессор, не хуже Word.

use Text::Autoformat;
$formatted = autoformat $rawtext, { left=>8, right=>70,
justify => centre,
case => lower
};

И это самое малое, что можно сделать с текстом с помощью Text::***. Конвертирование форматов разных ОС, фильтрация, макросы, текстовая графика и многое другое. Что называется, "MustHave".

С кодировками Unicode и всеми проблемами, с ней связанными, вам помогут справиться модули Unicode::***

Модуль Unicode::String позволяет работать со строками этой кодировки, не перекодируя их вручную.

use Unicode::String qw(utf8 utf16 hex);
$u = utf8("Unicode uniform string");
$u16 = $u->utf16; # Перевод в utf16
$hex = $u->hex; # в Hex-строку
$ucopy = $u->copy;
$u->chop;
$u->length;
$u->index($u2);
$u->substr($offset, $length);

Работать с форматом PDF (создавать, читать, писать) вам поможет модуль PDF со всеми своими подмодулями, а также семейство Text::PDF. Они предоставляют вам мощный интерфейс для всевозможных манипуляций с PDF-данными. Вы можете, например, написать скрипт, который будет выдавать красивый вариант страниц вашего сайта для печати. Правда, посетителям с подключением Dial-Up это будет не очень удобно =).

use PDF::Create;
$pdf = new PDF::Create(filename => HelloPerl.pdf,
Version => 1.2,
PageMode => UseOutlines,
Author => cmapul[0nline],
Title => Hello, Perl!,
  );
$root = $pdf->new_page(MediaBox => [ 0, 0, 612, 792 ]);
$page = $root->new_page;
$f1 = $pdf->font(Subtype => Type1,
Encoding => WinAnsiEncoding,
BaseFont => Helvetica);
$page->stringc($f1, 20, 300, 300,by cmapuk[0nline] );
$pdf->close;

LWP Cooking. Снова я возвращаюсь к вопросам работы с LWP, как и обещал, чтобы рассказать о модулях этого семейства подробнее. Несколько позже мы рассмотрим и модули более низкого уровня - Socket и IO::Socket. Самый простой способ использования LWP:

cmd> perl -MLWP::Simple -e "getprint http://www.comprice.ru;" >index.html

Если ваша консоль поддерживает перенаправление (символы ), то индексная страница сайта будет записана в index.html.

Теперь напишем что-нибудь посложнее. Создадим скрипт для скачивания архивов Perl-модулей с сайта ActiveState (www.activestate.com/PPMPackages/zips/6xx-builds-only/). Для начала определимся, какими возможностями должна обладать программа.

1) Скачивание списка модулей.

2) Вывод списка в файл.

2) Скачивание модулей выборочно по списку

3) Возможность соединения через прокси-сервер.

4) Сохранение архивов в заданной директории.

Теперь можно создать конфигурационный файл.

# pmdown.cfg
# Адрес страницы списка модулей
baseurl=http://www.activestate.com/PPMPackages/zips/6xx-builds-only
# Если прокси не используется, оставить эти поля пустыми
proxy_addr=192.168.0.1
proxy_port=3128
# Если не используется авторизация на прокси-сервере, эти поля оставить пустыми
proxy_user=cmapuk
proxy_pass=superpassword
# Директория для сохранения
savedir=/home/users/cmapuk/modules

Наша программа будет принимать 2 параметра в командной строке:

Ключ, определяющий действие, и имя файла, в следующих комбинациях:

cmd> pmdown -l list.txt скачать список модулей и записать в файл list.txt;
cmd> pmdown -d list2.txt открыть файл list2.txt и скачать все модули из списка.

При запуске без параметров будем выдавать help.

#!/path/to/perl
if(@ARGVproxy(http,"$CFG{proxy_addr}:-$CFG{proxy_port}") if $CFG{proxy_addr};
# Прописываем параметры авторизации, если определено $CFG{proxy_user}
$request->proxy_authorization_basic(-$CFG{proxy_user},$CFG{proxy_user}) if $CFG{proxy_user};
if($ARGV[0] eq "-l"){
         $request->uri($CFG{baseurl});
# Отправляем запрос. Ответ в $result
$result=$agent->request($request);
if($result->is_error()){
print "Error:".$result->message;
exit; # Если произошла ошибка, выводим текст и завершаемся
}
# Все ОК. Создаем из страницы список
my $list=$result->content();
my @zips=();
while($list=~/href="\/([^\/]+)\.zip"/){
push(@zips,$1); # В @zips список вида ModuleName
}
open(F,">$ARGV[1]")|| die "File-$ARGV[1]:$!";
print F join("\n",@zips);
close(F);
print "\n\n Ok! Check $ARGV[1]";
# Записали в файл и завершаемся
exit;
}elsif($ARGV[0] eq "-d"){
open(F,"$ARGV[1]")|| die "File-$ARGV[1]:$!";
chomp(@zips=); # Читаем список модулей
close(F);
for(@zips){
$request->uri("$CFG{baseurl}/$_.zip"); # Составляем адрес
$result=$agent->request($request, "$CFG{savedir}/$_.zip"); # запрашиваем
if($result->is_success()){ # Если все ок, файл сохранится
print "Module $_: saved.\n"; # А мы выводим сообщение
$ok++;
}else{
print "Module $_: error\n".$result->message()."\n";
$failed++; # Если произошла ошибка - пишем сообщение
}
}
  print "$ok modules saved\n$failed modules no saved";
exit; # Все. Подсчитали модули OK/NotOK и завершаемся
}else{
# Неправильные аргументы. Завершаемся
print "Type: \"cmd>pmdown h\" for help";
exit;
}

Пример кода не блещет красотой исполнения, но зато так выглядит нагляднее. В качестве "домашнего задания" могу предложить оптимизировать код примера или расширить его возможности. Если ваш новый скрипт будет работать, значит, я не зря потратил время, взявшись за написание этой статьи ;-).



www.comprice.ru
Скорая компьютерная помощь 02-12-2006
Вопрос-ответ 17-03-2008 Скорая компьютерная помощь
Уважаемые читатели! Мы продолжаем публикацию вопросов-ответов в рамках рубрики "F1-Help". Присылайте нам любые вопросы на компьютерную и телекоммуникационную тематику по адресу forum@comprice.ru, а мы постараемся вам ответить. Также по этому адресу вы можете оставлять свои пожелания в адрес нашего журнала, и то, о чем бы вы хотели прочитать на его страницах.Вопрос: Планирую приобрести пишущий DVD-привод, но достоверной информации найти практиче...


Вопрос - ответ 12-11-2007 Скорая компьютерная помощь
Вопрос: У меня возникла такая вот ошибка. При открытии приложения Nero Info Tool выдается "синий экран" со следующим содержимым:A problem has been detected and windows has been shut down to prevent damage to your computer If this the first time you"ve seen this Stop error screen, restart your computer.If this screen appears again, follow these steps: Check to be sure you adequate disk space. If a driver is identified in the Stop message, disa...


Вопрос - ответ 29-08-2007 Скорая компьютерная помощь
Уважаемые читатели! Мы продолжаем публикацию вопросов-ответов в рамках рубрики "F1-Help". Присылайте нам любые вопросы на компьютерную и телекоммуникационную тематику по адресу forum@comprice.ru, а мы постараемся вам ответить. Также по этому адресу вы можете оставлять свои пожелания в адрес нашего журнала, и то, о чем бы вы хотели прочитать на его страницах.Вопрос: Начал устанавливать WindowsXP на новый винчестер, в установщике разбил жесткий д...

Copyright © 2005
"service-centers.com.ua"


Rambler's Top100   Рейтинг@Mail.ru

Работа
Карта сайта
О сайте
Реклама
все объявления
поиск резюме
поиск вакансий
добавить резюме
добавить вакансию

Все объявления
Компьютеры, оргтехника
Автомобили
Продукты питания
Аудио, Фото, Видео
Связь
Отдых, путешествия
Мебель
Разное
Добавить объявление
 Автомобили
 Ремонтно-строительные услуги
 Пресс-релизы
 Железо
 Soft
 Мобильная планета
 Для милых дам
 Родительский клуб
 Недвижимость
 Домашний очаг, усадьба
 Строительство
 Обустройство и безопасность дома
 Сантехника