В своей скромненькой статье я расскажу о
программировании 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,",)
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:, то проверить строку на
существование текста ". Если найдётся - заменить на "ничто".
Вывести получившуюся строку в окно статуса
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. |