Я часто зависаю в ирке, на
далнет ру =), точнее, скока в инете сижу,
все в ирке зависаю. Так вот, обычно,
народ юзает мирк или пирч, я юзаю мирк,
и время от времени кто-нибудь да
реквестит моё время и версию клиента =)
Сиё занятие мне просто надоело и
почесав в затылочной части черепной
коробки я почитал рфц по IRC, не найдя
там ничего путного об этих реквестах,
я включил дебуг мод в ирке командой /debug
on, в результате одного сеанса с ирк
сервером и запросов самому себе у меня
был формат команды запроса и ответа
мирка на вышеупомянутые реквесты. Не
долго думая, я написал простенького
двустороннего клиента, работающего
между мирком и ирк сервером,
единственное удобство внешней
программы в том, что при выходе новой
версии не надо вновь ковырять
экзешник =) и подменять версию. К
сожалению, зная тока один язык кодинга,
Перл, релиз подмены версии клиента,
времени и даже кастом ответа на запрос
пинга, а также возможность прямо из
мирка посылать в статусное окошко
сообщения любого содержания,
реализованы в виде *.pl =)
Полезность этого примера
заключается в том, что вы увидите, как
просто работать с сокетом в качестве и
сервера и клиента, также я рассмотрю
здесь тот шматок кода, который
позволит вашим скриптам не
останавливать весь скрипт до
получения данных с МАНИПУЛЯТОРА, будь
то сокет или файл.
#Fake Reply coded by TEHb13 mail me: TEHb13@xakep.ru
if you have any questinos
#FR.pl
# Подключаем модуль Socket для работы с
сокетами
use Socket;
# Далее объявляем все нужные нам
переменные
$sp = chr(1); # Спец символ
используемый в ИРК протоколе
$server_port = '6613'; # Локальный
порт к которому буит подключаться
мирк
$remote_host = 'forest.dal.net.ru'; #
Удаленный ИРК сервер
$remote_port = '6667'; # Порт
удаленного ИРК сервера
$version = 'Совковая компиляция';
# Ответ на запрос о версии клиента
$time = 'пропил =)'; # Ответ на
запрос о времени на клиентской машине
# Сождание сокета для подключения к
ИРК серверу
socket(TO_SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
$internet_addr = inet_aton($remote_host) or die "Couldn't convert
$remote_host into an Internet address: $!\n";
$paddr = sockaddr_in($remote_port, $internet_addr);
connect(TO_SERVER, $paddr) or die "Couldn't connect to
$remote_host:$remote_port : $!\n";
# Отключение буферизации, для
танкистов именно из-за нее скрипты
работающие с сокетами выкидывают вам
ошибку 500
$old_filehandle_1 = select(TO_SERVER);
$| = 1;
select($old_filehandle_1);
# Создание сокета для локального
сервера к которому будет подключен
мирк
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
$my_addr = sockaddr_in($server_port, INADDR_ANY);
bind(SERVER, $my_addr) or die "Couldn't bind to port $server_port
: $!\n";
listen(SERVER, 1) or die "Couldn't listen on port $server_port :
$!\n";
# Основной цикл, работает пока мирк
подключен к локальному серверу
while (accept(CLIENT, SERVER)) {
# Опять же отключение буферизации но
для другова манипулятора
$old_filehandle_2 = select(CLIENT);
$| = 1;
select($old_filehandle_2);
# Самое интересное, создание двух
параллельных процессов, для того
чтобы, скрипт не останавливался до тех
пор пока в манипулятор не попадут
данные
die "can't fork: $!" unless defined($kidpid = fork());
# Собственно работа с двумя процессами
if ($kidpid) {
while (defined ($line = <CLIENT>)) {
print TO_SERVER $line;
}
# Убъет процессы как только мирк
отключится от локального сервера
kill("TERM" => $kidpid);
}
else {
while (defined ($line = <TO_SERVER>)) {
# Собственно в этой части
подделывается ответ о версии и
времени =)
if ($line=~/:.VERSION$sp/){
if ($line=~/!/){$fline=$`; $fline=~s/://;}
print TO_SERVER "NOTICE $fline :$spON VERSION REPLY ->
$version$sp\n";
}
elsif ($line=~/:.TIME$sp/){
if ($line=~/!/){$fline=$`; $fline=~s/://;}
print TO_SERVER "NOTICE $fline :$sp TIME $time$sp\n";
}
else {
print CLIENT $line;
}
}
}
exit;
}
# Закрываем сокет раз
close(SERVER);
# Закрываем сокет два
close(TO_SERVER);
# Вот собственно и Все.
www.xaker.ru