Back Content Forward

В своей скромненькой статье я расскажу о программировании TCP сокетов в mIRC. Почему я решил написать именно о сокетах? Потому что это интересно%).
Для экспериментов рекомендую использовать чистый mIRC. Для этого скопируйте файл mirc.exe в какой ни будь каталог, и запустите его.

Для начала приведу порядок работы с сокетами.
1) открываем сокет на нужный нам адрес в сети командой sockopen
1.1) ожидаем подключения к указанному порту. socklisten sockname порт
1.2) создаём обработчик события, когда кто-то пытается подключиться к прослушиваемому порту. on 1:socklisten:sockname: { комманды }
1.3) разрешаем (или неразрешаем) создание соединения. sockaccept sockname
2) создаём обработчик события на открытие сокета. on 1:sockopen:sockname: { команды которые должны выполниться в результате открытия сокета с именем sockname }
3) далее создаём обработчик события чтение из сокета. on 1:sockread:sockname: { команды }
4) потом, если требуется создаём обработчик события закрытия сокета удалённым клиентом. on 1:sockclose:sockname: { команды }
5) закрываем сокет. sockclose sockname


Начну с популярной задачи, выдирания определённого текста из страницы в интернете.
Скрипт будет посылать запрос на сайт ripe.net (база данных по ip адресам), получать страницу, обрабатывать её, и выводить в удобном виде необходимую информацию.
Первое что надо сделать, это создать алиас с командой для запуска скрипта. Нажмите Alt + R(переход в редактор скриптов, вкладка Remote). В самом начале пишем:

1> alias ripe {

1> - создаём алиас с именем ripe. Это можно было сделать и во вкладке Aliases редактора скриптов, но приятней когда всё находится в одном месте.

alias ripe {
1> sockopen ripe ripe.net 80
2> %ripe = $1
}

1> - открываем сокет с именем ripe, на аддрес ripe.net, и порт 80.
2> - создаём переменную %ripe и присваиваем ей первый аргумент команды.

Алиас создан. Теперь если ввести /ripe "что-нибудь" откроется сокет на сайт ripe.net и создастся переменная %ripe со значением равным тому чего вы ввели после команды /ripe.
Теперь необходимо создать обработчик события на открытие сокета.

1> on 1:sockopen:ripe: {
2> if ($sockerr > 0) return
3> sockwrite -n $sockname GET /fcgi-bin/whois?form_type=simple&full_query_string=&searchtext= $+ %ripe $+ &submit.x=0&submit.y=0 HTTP/1.1
5> sockwrite -n $sockname Host: ripe.net $+ $str($crlf ,2)
6> unset %ripe
}

1> - создаём обработчик события на открытие сокета с именем ripe.
2> - если идентификатор $sockerr возвратит значение больше нуля, то невыполнять дальше скрипт.
3> - посылаем в сокет запрос страницы с информацией об ip адресе, который указывался в качестве параметра команды /ripe. Опция -n добавляет символы CRLF к строке
5> - посылаем в сокет адрес сервера к которому коннектимся
6> - удалить переменную %ripe

Теперь после отсылки запроса на сайт, надо прочитать ответ сайта.

1> on 1:sockread:ripe:{
2> if ($sockerr > 0) return
19> :nextread
3> sockread %ripe.r
4> if ($sockbr == 0) return
5> if (</pre><pre><b><u>inetnum</u></b>: isin %ripe.r) {
6> %ripe = 1
7> echo -s $chr(160)
8> echo 11 -s Inetnum $+(,$right(%ripe.r,-34))
}
9> if (</pre><pre><b><u>route</u></b>: isin %ripe.r) %ripe = 0
10> if (</pre><pre><b><u>organisation</u></b>: isin %temp1) %ripe = 0
11> if (</pre><pre><b><u>role</u></b>: isin %temp1) %ripe = 0
12> if (</pre><pre><b>person</b>: isin %ripe.r) {
13> %ripe = 1
14> echo -s $chr(160)
15> echo 11 -s Person $+(,$right(%ripe.r,-25))
}
16> if (%ripe == 1 && netname: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
17> if (%ripe == 1 && descr: isin $left(%ripe.r,12)) echo 11 -s $replace(%ripe.r,&quot;,)
if (%ripe == 1 && remarks: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
if (%ripe == 1 && changed: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
if (%ripe == 1 && notify: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
if (%ripe == 1 && address: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
if (%ripe == 1 && phone: isin $left(%ripe.r,7)) echo 11 -s %ripe.r
if (%ripe == 1 && fax-no: isin $left(%ripe.r,12)) echo 11 -s %ripe.r
if (%ripe == 1 && e-mail: isin $left(%temp1,12)) echo 11 -s %ripe.r
18> goto nextread
}

1> - создаём обработчик события чтения из сокета.
2> - если идентификатор $sockerr возвратит значение больше нуля, что означает ошибку, то невыполнять дальше скрипт.
3> - записать строку текста которая пришла из сокета в переменную %ripe.r
4> - если количество принятых байтов равно нулю, что может означать конец передачи сервером данных, то невыполнять дальше скрипт.
5> - если есть строка </pre><pre><b><u>inetnum</u></b>: в переменной чтения сокета.
6> - то создать переменную %ripe со значением 1. Эта переменная нужна для того чтобы исключить блок данных route, который может содержаться на
интернет странице с ответом на наш запрос. Этот блок всё равно не несёт никакой интересной информации. Вообщем поставив значение 1 переменной %ripe мы сказали скрипту что сейчас приходящие данные можно обрабатывать.
7> - вывести в окно статуса пустую строку
8> - вывести в окно статуса диапазон ip адресов
9> - если есть строка </pre><pre><b><u>route</u></b>: в переменной чтения сокета, то присвоить значение 0 переменной %ripe. Что означает необрабатывать приходящие данные
10>- если есть строка </pre><pre><b><u>organisation</u></b>: в переменной чтения сокета, то присвоить значение 0 переменной %ripe.
11>- если есть строка </pre><pre><b><u>role</u></b>: в переменной чтения сокета, то присвоить значение 0 переменной %ripe.
12>- если есть строка </pre><pre><b>person</b>: в переменной чтения сокета
13>- присвоить переменной %ripe значение 1
14>- вывести в окно статуса пустую строку
15>- вывести в окно статуса имя ответственного лица
16>- если %ripe равен 1, и в %ripe.r есть netname:, то вывести в окно статуса эту строку
17>- если %ripe равен 1, и в %ripe.r есть descr:, то проверить строку на существование текста &quot;. Если найдётся - заменить на "ничто". Вывести получившуюся строку в окно статуса
18>- перейти на метку nextread
19>- выполнить команды ниже

После того как всё это написали, жмём кнопочку ОК. После пишем /ripe 213.219.216.46 и радуемся.

С первым примером надеюсь всё понятно. Теперь опишу ситуацию, когда надо что бы клиент подключился к вам на определённый порт.
Для этого первым делом надо открыть порт. Делается это командой socklisten.

alias listen {
1> socklisten listen 22222
}

1> - ожидаем подключение на 22222 порту. listen - имя соединения

1> on 1:socklisten:listen: {
2> sockaccept listen2
3> sockwrite -n listen2 hello $sock(listen2).ip
4> echo -s Обнаружено подключение.
5> sockclose listen2
6> sockclose listen
}

1> - Обработчик вызывается, когда кто-то пытается подключиться к прослушиваемому порту.
2> - создаём соединение с именем listen2. Соединение listen всё ещё слушает 22222 порт.
3> - посылаем строку hello ip_адрес_клиента
4> - выводим в окно статуса сообщение о попытке подключения к прослушиваемому порту
5> - закрываем сокет с клиентом
6> - закрываем сокет прослушивания порта

Всё. Пишем /listen. Открываем телнет, конектимся на локалхост, порт 22222. Если всё правильно, то на экране должна появиться строка hello local_ip.

На этом остановимся. Надеюсь эта статья поможет вам разобраться с програмированием сокетов в mIRC%).
Параметры и описание всех команд можно посмотреть в хелпе mIRC.

Back Content Forward