В этой статье я рассмотрю создание простого чата на Perl. Чат будет состоять из консольного сервера и клиента с GUI на основе Tk. Для начала реализуем серверную часть.
В серверной части мы не будем использовать процессы или потоки, а вместо этого воспользуемся мультиплексированием. Мультиплексирование довольно просто реализуется с помощью модуля IO::Select, который является классом-оболочкой над системной функцией select.
Функция select позволяет определить готовность дескриптора к записи/чтению. Также стоит отметить, что при использовании select следует избегать использования блокирующих вызовов, как, например, print, read, вместо них необходимо использовать syswrite, sysread.
Читать далее «Пишем простое клиент-серверное приложение на Perl»
Метка: сокеты
Модуль для работы с Web
Написал простой модуль для работы с web. Модуль довольно легкий, основан на IO::Socket::INET и IO::Socket::SSL.
Конструктор:
new()
new(arg => value, arg => value)
Создает объект, который используется для дальнейших запросов. Доступные аргументы: agent (user-agent, который будет использоваться в запросе), timeout (таймаут соединения).
Методы:
set_cookie($arg)
Устанавливает аргумент в качестве кукисов.
header(%arg)
Устанавливает дополнительные заголовки.
proxy_auth($login, $passw)
Устанавливает логин и пароль для авторизации при работе с http-прокси.
socks_auth($login, $passw)
Устанавливает логин и пароль для авторизации при работе с socks-прокси.
proxy($proxy_type, $proxy)
Включает работу через прокси.
$proxy_type может принимать следующие значения: 0 - без прокси, 1 - http-прокси, 2 - socks5 прокси.
$proxy в формате ip:port
request($method, $host, $port, $uri, $payload, $limit)
Метод для непосредственного выполнения запроса
$method - GET, POST, HEAD,
$host - адрес сайта с http:// (например, http://rambler.ru),
$port - порт,
$uri - путь запроса (например, /index.php),
$payload - тело POST-запроса,
$limit - количество байт, которые необходимо считать из сокета (0 - считать весь ответ).
Примеры работы с модулем
Получение веб-страницы в переменную и вывод содержимого ответа на экран:
1 2 3 4 |
use Web; my $w = Web->new(timeout => 10, agent => 'FireFox'); my $page = $w->request('GET', 'http://rambler.ru', 80, '/', '', 0); print $page; |
Работа через прокси:
1 2 3 4 5 |
use Web; my $w = Web->new(timeout => 10, agent => 'FireFox'); $w->proxy(2, '127.0.0.1:1080'); #2 - socks5 прокси my $page = $w->request('GET', 'https://mini.webmoney.ru', 443, '/', '', 0); print $page; |
POST запрос через прокси:
1 2 3 4 |
use Web; my $w = new Web; my $page = $w->request('POST', 'http://site.com', 80, '/auth.php', 'login=vasya&pass=petya', 0); print $page; |
Скачать: web.pm
Класс для работы с сокетами
PHP-класс, позволяющий просто работать с сокетами без лишних усилий.
Способен получить страницу по HTTP/1.1 и с использованием Keep-Alive-соединения, а также нормально парсит страницы с Transfer-Encoding: chunked.
Кроме того, если страница выдаётся в gzip, то есть возможность автоматической распаковки содержимого.
Класс также поддерживает прокси и может парсить cookies, выдаваемые ему сайтом.
По умолчанию класс работает через функции socket_*** (не поддерживаются денвером), но можно использовать и привычные fsockopen, правда, тогда через Keep-alive работать не получится.
Пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php /* скрипт получает страницу www.google.ru через HTTP/1.1 и Connection: keep-alive. */ require("websock.php"); //подключение файла с классом //укажите в конструкторе третий параметр false, тогда вместо socket_*** будут использоваться fsock-функции $s=new websock('www.google.ru',80); //создание нового сокета //$s->set_proxy('203.162.2.139','80'); //Если надо прокси, его можно установить следующим образом $s->sconnect(); //подключаем сокет $s->set_connection(1,300); //keep-alive: 300 $s->set_proto('1.1'); //HTTP 1.1 $s->get_header('/'); //формируем заголовок для запроса к серверу (получаем корень http://mail.ru/) $s->swrite(); //пишем его в сокет $ret=$s->http11read(); //универсальная функция чтения из сокета, неважно, какие заданы параметры подключения. Читаем всё возвращённое содержимое. print $ret[0]; //$ret[0] - заголовки, $ret[1] - содержимое $s->sclose(); //закрываем соединение ?> |
Ещё пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php /* скрипт просто получает cookies со страницы http://bash.org.ru */ require("websock.php"); //подключение файла с классом $s=new websock('bash.org.ru',80); //создание нового сокета $s->sconnect(); //подключаем сокет $s->get_header('/'); //формируем заголовок для запроса к серверу (получаем корень http://bash.org.ru/) $s->swrite(); //пишем его в сокет $ret=$s->http11read(); //универсальная функция чтения из сокета, неважно, какие заданы параметры подключения. Читаем всё возвращённое содержимое. print $s->get_cookie($ret[0]); //получаем Cookies в виде строки $s->sclose(); //закрываем соединение ?> |
Дополнительные комментарии по всем функциям класса можно найти в его коде.
UPD от 30.03.09: Выкладываю новую версию, в которой добавлена поддержка прокси с паролями, socks5, socks5 с паролями и исправлен парсинг cookies, а также добавлены простые функции get и post.
UPD от 02.04.09: еще некоторые мелкие поправки
UPD от 16.04.09: исправлен косяк при работе с прокси