В продолжение темы про сокеты, я решил расписать их особенности на конкретных простых примерах. Почему простых? Чтобы ты смог подвести под мою основу свой собственный скрипт 🙂 Мои примеры будут как бы подсказкой, дополнительной опорой для изучения тобой Perl.

Итак начнем. Самое интересное в сокетах, на мой взгляд — отправка и получение данных. Как я уже сказал, можно обойтись самым простым решением: print и <>. Но для особых случаев, когда в сокете должны быть данные без символа перевода строки (\n), либо пересылка данных в сокет без него, этими операторами не обойтись. Можно использовать, либо объектовые методы $self->recv и $self->send твоего сокета, либо заюзать системные функции языка aka sysread() и syswrite(), но обо всем
по порядку.

Для ожидания данных используют модуль Select.pm, который смотрит, доступен ли сокет для чтения и для записи, и если доступен — с ним производятся нужные операции.

Структура IRC-бота

Я взял самый наболевший и популярный пример, который выполнил в считанные строки кода :). Конечно, умело написанный парсер возвратных данных и управление немного его приукрасит, но, как я уже сказал, это твоя задача 🙂 Собственно скрипт:

#!/usr/bin/perl

use IO::Socket;
use IO::Select;

$sock=IO::Socket::INET->new(«irc.server.ru:6667») || die «can\’t create sock\n»;

$sock->autoflush(1);
$select=new IO::Select($sock);
syswrite($sock,»USER test test test test\nNick Testor\n»);
syswrite($sock,»JOIN #xakep\n»);

while(1) {
foreach $s ($select->can_read) {
if ($s eq $sock) {
$sock->recv($msg,1024);
print «Server send to me: $msg\n»;
}
}
}

Поясню, как все это работает. В начале, заюзываем 2 модуля Select.pm и Socket.pm. Затем создаем сокет с IRC-сервером (на этом останавливаться не буду, создание сокетов было описано в
первой части статьи) и отключаем в нем буферизацию. Затем идет создание идентификатора $select и занесение в него нашего созданного сокета. После этого, можно будет смотреть за данными в сокете.

Затем пишем в сокет syswrite()’ом идентификационные строки (как IRC-man ты их, конечно, знаешь).
Затем порождаем бесконечный цикл, в котором следим за тем, можно ли, прочитать из сокета данные ($select->can_read возвращает ссылку на массив, в котором хранятся идентификаторы сокетов, где есть инфа для чтения). Сравниваем: если элемент массива соответствует нашему сокету, то читаем из него сообщение и выводим на консоль. Получается быстро и красиво :). Но без парсера этих самых сообщений, твой бот слетает по таймауту с сервера, поэтому не слишком обижайся на него 😉 Просто анализируй каждую строку и направляй ее куда следует. Вот пожалуй и все об этом несложном ламаботе :).

Мучаем WWW-сервер

Уж не знаю для чего тебе может пригодится следующий скрипт 🙂 Может ты его захочешь заюзать для DDoSа какого-нибудь сервака, или в мирных целях — например для раскрутки твоего любимого сайта. Скрипт выполняет следующую роль: плодит нужное количество потомков и просит страницу с Web-сервера 🙂 Все просто как мир. Собственно, код:

#!/usr/bin/perl

use IO::Socket;

$host=’rambler.ru’;
$port=80;
$dir=’/index.html’; ## Сервер, порт и собственно файл, который хотим получить.
$threads = $ARGV[0] || 10; ## Количество потомков задаем в параметре скрипта, или 10 по дефолту
$debug=1; ## Мусорить на экран или нет решать тебе, по умолчанию, нет

init(); ## Идем на главную процедуру.

sub init { ## Собственно, главная процедура 🙂
for (1..$threads) { ## Создаем цикл от единицы до заданного числа
unless($pid=fork()) { ## Ответвляем процесс
print «starting!\n» if ($debug); ## Флудим в консоль, если $debug=1
fconnect(); ## Коннектимся каждым потомком к серверу.
}
}
}

sub fconnect {
my($sock);
$sock=IO::Socket::INET->new(«$host:$port») || return 1; ## Создаем сокет
print $sock qq~GET $dir HTTP/1.0
Host: $host

~; ## Запрашиваем у Web-сервера нужный документ
$count=sysread($sock,$msg,1024); ## Читаем ответ
print «sock is alive\n» if ($count > 0 && $debug); ## Если ответ был успешно доставлен и дебаг включен — опять флудим 🙂
close($sock); ## Закрываем сокет
exit; ## И завершаем потомок! Этот выход очень важен (иначе будет переполнение в таблице процессов) 
}

И тут, опять же все просто, многопотоковость очень гибко взаимодействует с сокетами, и выполняет нужную функцию. Сам посуди, откроется одновременно нужное количество потомков и будут обращаться к сокету, что гораздо быстрее последовательных операций, особенно если канал это позволяет :).

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

Удачи в кодинге!

Оставить мнение

Check Also

Давай напишем ядро! Создаем простейшее рабочее ядро операционной системы

Разработка ядра по праву считается задачей не из легких, но написать простейшее ядро может…