Гостевая
Форум
Разделы
Главная страница
Js скрипты
Php скрипты
Html шаблоны
Книги по Web дизайну
Статьи


Главная страница статей --> Программирование, заработок, оболочки

Perl и сокеты. Часть 1

Источник: linuxcenter.ru

В этой статье рассматривается один из способов взаимодействия с сокетами языка Perl с помощью стандартного модуля Socket. Предполагается, что читатель знаком с базовым синтаксисом Perl и стеком протоколов TCP/IP, поэтому углубляться в эту тему я не стану. Если вас что-то интересует из вышеперечисленного, спросите у googla. Итак, приступим.

Для начала разберемся, что из себя представляет этот загадочный «сокет». Сокет — это конечная точка соединения, можно сказать, «канал», по которому мы можем «общаться» с удаленным процессом, отправляя и получая требуемые сообщения. Для чего это нужно? Для обмена данными с удаленной машиной. Зачем? Что ж, давайте разбираться, но по порядку. Рассмотрим устройство сокета:

  1. Домен сокета:
    В книге «Разработка сетевых программ на Perl», написанной небезызвестным Линкольном Штайном, на мой взгляд, было дано наиболее точное и понятное определения термина «домен сокета»: «Домен сокета определяет семейство сетевых протоколов и схем адресации, поддерживаемых константами». На данный момент существует лишь два общепринятых домена: AF_INET, применяющийся для работы с сетями TCP/IP, и AF_UNIX, применяющийся для межпроцессного взаимодействия на одном хосте (данный домен может быть реализован и на системах, отличных от UNIX).
  2. Тип сокета:
    Определяет особенности связи через сокет. Это может быть как непрерывный поток данных (SOCK_STREAM), так и данные, передаваемые отдельными пакетами (SOCK_DGRAM). Язык Perl также поддерживается доступ к внутренним протоколам и интерфейсам через константу SOCK_ROW, поддерживаемую через модуль Net::Raw.
  3. Протокол сокета:
    Думаю, это пояснять не стоит, как и тот факт, что протоколы обозначаются фиксированными целыми числами. Протоколы TCP и UDP поддерживаются API-интерфейсом языка, ICMP можно подключить через модуль Net::ICMP, raw можно подключить через Net::Raw.

Сокеты бывают дейтаграмными (обеспечивают ненадежную передачу данных без установления соединения — протокол UDP) и потоковые (напротив, обеспечивают надежную упорядоченную передачу данных в виде потока данных, устанавливая постоянное соединение).

Вы еще не устали от теории? Давайте перейдем к практике. Чтобы понять основы основ, придется написать практически бесполезный скрипт клиента службы времени, который выдает текущую дату и время. Делать мы это будем через протокол daytime (RFC867). Что ж, приступим:

#!/usr/bin/perluse strict;# подключаем модуль Socketuse Socket;# далее мы вводим константу, содержащую# адрес сервера, к которому мы должны подключиться.# но, чтобы корректно сформировать адрес сокета, # мы должны ввести IP-адрес требуемого хоста. т.е. # если я хочу подключиться к s2.daytime.net.ru,# то мне придется написать: # use constant DEF_ADDR => 217.20.189.83# (это ip-адрес хоста s1.daytime.net.ru). use constant DEF_ADDR => 212.9.235.98;# далее вводим константу PORT, которая будет содержать # номер порта, к которому мы будем подключаться. # в данном случае используется протокол TCP, имеющий # стандартный номер порта — 13.use constant PORT => 13;# чтобы создать соединение с сокетом, нужно определить # протокол, с которым будем работать. к сожалению, # мы не можем написать просто TCP, программа нас # не поймет, для нее это просто очередной набор # символов. по некоторым непонятным мне причинам # каждый протокол имеет свой фиксированный номер. # у протокола TCP этот номер равен 6. данное число # говорит программе при соединении с сокетом, что мы хотим# использовать именно TCP, а не UDP или какой-либо еще.use constant TCP => 6;# здесь предоставляется возможность пользователю ввести # адрес того хоста, к которому он хочет подключиться. # если ничего не введено, программа будет использовать # стандартный адрес.my $addr = shift  DEF_ADDR;# как я уже упоминал, адрес сокета включает в себя # номер порта и ip-адрес хоста, к которому мы собираемся # подключиться. но, по сложившимся обстоятельствам,# для связи используются ip-адреса в двоичном виде, # так легче машинам, однако, представляете, каково # читать такое человеку? естественно легче воспринимать # что-нибудь вроде того же 127.0.0.1. чтобы перевести # привычный нам ip в понятный программе двоичный вид, мы# используем функцию inet_aton(arg), # где arg — «человеческий» ip-адрес. # (кстати, чтобы перевести двичный ip в человеческий можно # использовать функцию inet_ntoa,# my $ip = inet_ntoa($packed_ip), # где $packed_ip — двоичный адрес).my $packed_addr = inet_aton($addr);# теперь нужно сформировать адрес сокета, # что делается с помощью функции # my $socket_addr = sockaddr_in($port, $packed_addr), # которая «объединяет» номер порта($port) # и двоичный ip-адрес($packed_addr) в формат,# понятный для сокета.# кстати, чтобы распаковать $socket_addr обратно # в номер порта и двоичный ip-адрес, можно использовать # эту же функцию, только в списковом контексте: # my ($port, $packed_addr) = sockaddr_in($socket_addr).my $socket_addr = sockaddr_in(PORT, $packed_addr);# далее требуется создать сокет с помощью функции# socket(DESCR, SOCK_DOMEN, SOCK_TYPE, PROTOCOL), # где DESCR — дескриптор, SOCK_DOMEN — домен сокета, # SOCK_TYPE — тип сокета, # PROTOCOL — номер используемого протокола.socket(SOCK, AF_INET, SOCK_STREAM, TCP) or   die "не удалось создать к сокет =(";# после того, как мы создали сокет, можно # устанавливать соединение с удаленным хостом.# для этого используем функцию # connect(DESCR, $socket_addr),# где DESCR — дескриптор созданного сокета, # а $socket_addr — созданный адрес сокета.connect(SOCK, $socket_addr) or    die "не могу подключиться к сокету =(";# запишем полученные данные в переменную # и закроем соединениеmy $date = <SOCK>;close SOCK;# серверы daytime возвращают время по Гринвичуprint "$date\n";

Вот и все. Осталось запустить скрипт (пусть он будет назван socket.pl):

$ ./socket.pl
Sat Jun 11 00:09:03 2005

Все. Лично я постоянно путаюсь с числовыми значениями протоколов, номерами портов, ip-адресами и прочими вещами, которые нужно запоминать. К счастью, Perl освобождает нас от всего этого несколькими полезными функциями. Запомнить их намного легче, чем все вышеперечисленное.

my $packed_addr = gethostbyname($name), где $name — имя хоста, к которому мы хотим подключиться. Например, если мы напишем my $packed_addr = gethostbyname(s2.daytime.net.ru), то переменная $packed_addr будет содержать ip-адрес s2.daytime.net.ru в двоичном виде.

$port_number = getprotobyname($protocol), где $protocol является именем требуемого протокола. Например, если $port = getprotobyname(tcp); $port будет содержать число 6.

$port = getservbyname($service, $protocol), где $service — имя сервиса, а $protocol — имя протокола. Данная функция возвращает номер порта. Т.о. если мы напишем $port = getservbyname(daytime, tcp), переменная $port будет содержать 13.

$service = getservbyport($port, $protocol), где $port — номер порта, а $protocol — имя протокола. Функция возвращает название службы, соответствующей введенным данным. Например, в случае $service = getservbyport(13, tcp), $service будет содержать daytime;

А теперь перепишем нашу программу, используя полученные знания о новых функциях:

#!/usr/bin/perluse strict;use Socket;# имя сервераuse constant DEF_ADDR => s2.daytime.net.ru;my $packed_addr = gethostbyname(shift  DEF_ADDR) or   die "не могу найти данный хост =(";my $protocol = getprotobyname(tcp);my $port = getservbyname(daytime, tcp) or    die "не могу обнаружить порт =(";my $socket_addr = sockaddr_in($port, $packed_addr);socket(SOCK, AF_INET, SOCK_STREAM, $protocol) or    die "не могу создать сокет =(";connect(SOCK, $socket_addr) or    die "не могу соединится с сокетом =(";my $date = <SOCK>;close SOCK;print "$date\n";

Вот и все. В следующей статье напишем нечто более полезное и научимся использовать гораздо более простой способ взаимодействия с сокетами, реализуемый модулем IO::Socket.



Похожие статьи:
- Честно слово!
- Flash-технология. Недостатки
- Удивительное рядом: установка Mac OS X на PC в эмуляторе PearPC
- Практика развития ресурса от лидеров поискового продвижения
- Звуковые редакторы
- Практический опыт продвижения интернет-магазина
- Perl и сокеты. Часть 2
- “Безопасные” сайты
- Версия сайта для печати средствами CSS
- Береги честь смолоду: прячем e-mail адреса от спама
- Выпадающее меню на CSS и JavaScript
- Валидность HTML
- Игры в ассоциации


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |
[0.001]