Похожие статьи

Perl и сокеты. Часть 2 (95,45%)
В статье рассматривается работа с сокетами на Perl с помощью стандартного модуля Socket на примере клиента, получающего данные о погоде с weather.yandex.ru. А также работа с сокетами через модуль IO::Socket на примере клиента службы времени…

Миф о специалисте (35,9%)
Один из специалистов по продажам в интернет жалуется другому: знаешь, вот я провожу семинары и тренинги, чтобы научить людей зарабатывать в Сети. Я говорю им: у вас есть продукт, давайте посмотрим, как сделать его прибыльным продуктом, как изучить электронный рынок, как правильно предложить товар…а они после курса обучения начинают писать и…

История создания и раскрутки одного сайта (часть 1) (35,62%)
В этой статье мне бы хотелось поделиться с читателями своим небольшим опытом в создании и раскрутке небольшого проекта и охарактеризовать основные моменты этих процессов на примере своего сайта. Я расскажу о том, с чего начинается создание сайта, о выборе хостинга, о системах подсчета статистики и о регистрации в по в поисковых системах и каталогах…

Автор: Кручинин Даниил aka Asgard
dubalom(DOG)gmail(DOT)com

Дата публикации 14-06-2005 19:03
Статья просмотрена 10677 раз

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

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

  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/perl

use strict;
# подключаем модуль Socket
use 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/perl

use 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.

Похожие статьи

Дайте вашим посетителям текст (35,29%)
Исследования показали, что интернет-сайты кардинальным образом отличаются от печатных изданий. В чем заключаются эти отличия, как они влияют на поведение пользователей, каким должен быть правильный контент-проект — ответы на все эти вопросы вы найдете в данной статье…

Могут ли ваши посетители доверять вам? (33,33%)
Соблюдение конфиденциальности личной информации в Интернете становится все более и более важным вопросом для рядовых пользователей Сети. В некоторых случаях посетителям сайтов приходится целиком и полностью полагаться на порядочность владельца сайта. И в этом смысле вопрос доверия посетителя к сайту в целом становится ключевым…

CSS: врезка к статье (33,33%)
Мы часто сталкиваемся в журналах и газетах с информационными блоками, которые визуально выделены и по смыслу несколько оторваны от основного содержания. Это не прихоть верстальщика или редактора, эти блоки давно заняли заслуженное место в бумажных изданиях. К сожалению, в интернет-публикациях врезки встречаются нечасто. О создании врезок с помощью CSS как раз и рассказывается в статье…

История создания и раскрутки одного сайта (часть 2) (32,88%)
В этой статье мне бы хотелось поделиться с читателями своим небольшим опытом в создании и раскрутке небольшого проекта и охарактеризовать основные моменты этих процессов на примере своего сайта. Далее я расскажу о методах раскрутки сайта и проиллюстрирую их на конкретных примерах своего проекта ПартА…

Валидность HTML (32,43%)
На примере известных веб-сайтов видно, что практически никто не поддерживает стандарт HTML. И главная причина в том, что дизайнеры абсолютно не задумываются о поддержке стандарта, хотя это достаточно просто. В статье рассматриваются основные моменты, которые приводят к невалидности документов, и показывается, что исправление таких ситуаций не требует кардинальных изменений на сайте…

← Раздел «Программирование: Perl» | Комментарии (3) →

Ваше имя: 

Цифры с картинки:
Включите графику в браузере

Ваши комментарии:

Все поля формы обязательны для заполнения.
Комментарий: Любые HTML-теги в сообщениях запрещены.
Гиперссылки в комментариях не работают — добавлять спам бесполезно!
Максимальная длина комментария — 5000 символов.
Комментарии, не имеющие отношения к статье, будут удалены.

 

Perl и сокеты. Часть 2 В статье рассматривается работа с сокетами на Perl с помощью стандартного модуля Socket на примере клиента, получающего данные о погоде с weather.yandex.ru. А также работа с сокетами через модуль IO::Socket на примере клиента службы времени…

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

Perl и сокеты. Часть 2 В статье рассматривается работа с сокетами на Perl с помощью стандартного модуля Socket на примере клиента, получающего данные о погоде с weather.yandex.ru. А также работа с сокетами через модуль IO::Socket на примере клиента службы времени…

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