RTFM! статьи, советы, скрипты
::Заработок с помощью сайта ::JScript по-русски! ::Все русские мануалы::
МЕНЮ
О САЙТЕ
НОВОСТИ
СТАТЬИ
КНИГИ
АППЛЕТЫ
СВЯЗЬ

СЧЕТЧИКИ
Rambler's Top100
Рейтинг@Mail.ru
Яндекс цитирования

Perl и работа с сокетами

Автор: Philip A. Koryaka Сайт: http://www.perl.ru/     Рейтинг: N/A из 7       <<НАЗАД
   
   
   Иногда возникает необходимость из программы на перле соединиться с другим сервером и передать/принять какую-нибудь информацию. Как правило, возникает необходимость работать с протоколом HTTP, но поняв основные принципы взаимодействия между двумя серверами и прочитав спецификацию интересующего протокола, можно написать программу, работающую практически через любой протокол. Далее мы рассмотрим работу с протоколом HTTP.
   
   Первое что нам понадобится это - сокеты (sockets). Сокет - это канал, проложенный между сервером на котором запускается программа и сервером, с которым мы хотим установить соединение. Для работы с сокетами в перле есть модуль - Socket.
   
   Для создания сокета используется функция socket. Формат ее таков:
   
   
   
   
   socket(SOCK, DOMAIN, TYPE, PROTOCOL);
   
   
   
   
   Данная функция открывает сокет и привязывает его к указателю SOCK.
   
   DOMAIN - это коммуникационный домен. Не нужно его путать с доменом сервера с которым мы соединяемся. В нашем случае это будет Internet домен (бывает еще Unix домен) а потому указываем: PF_INET
   
   TYPE - это тип сокета. Мы будем использовать SOCK_STREAM - этот тип обеспечивает последовательный, надежный поток байтов. Так же существуют Datagram socket и Raw socket, но о них как-нибудь в другой раз.
   
   PROTOCOL - протокол, по которому будет устанавливаться соединение. В нашем случае это tcp поэтому вместо PROTOCOL вставляем следующее:
   
   
   
   
   getprotobyname('tcp');
   
   
   
   
   Помимо tcp можно использовать udp, ip и т.д. Функция getprotobyname возвращает название протокола в более удобном для функции socket виде.
   
   Итак создаем сокет:
   
   
   
   
   socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
   
   
   
   Когда сокет готов, можно подключаться к конкретному серверу. Для этого нам нужен адрес сервера и порт. Предварительно, необходимо сделать следующее:
   
   
   
   
   $iaddr = inet_aton($host); # Конвертирует имя сервера в # бинарную последовательность.$paddr = sockaddr_in($port, $iaddr); # Упаковывает все в понятную функции# connect последовательность.
   
   
   
   Теперь все готово и мы можем использовать функцию connect:
   
   
   
   
   connect(SOCK, $paddr);
   
   
   
   После соединения с сервером, мы можем передавать и принимать некоторую информацию. Рассмотрим процесс передачи и приема данных, более подробно, на примере соединения с Web-сервером и получения с него некоторого документа. Для отправки сообщения через сокет служит функция send:
   
   
   
   
   send (SOCK, "То что шлем", 0);
   
   
   
   Вместо 0 может быть один из перечисленных флагов:
   
   MSG_OOB - Посылать/получать данные, характерные для сокетов типа SOCK_STREAM
   
   MSG_DONTROUTE - Посылать данные без маршрутизации пакетов. Как правило используется диагностическими программами и процессами управляющими таблицами маршрутизации.
   
   Для приема данных через сокет, используем стандартную операцию:
   
   
   
   
   @data=&lt;SOCK&gt;;
   
   
   
   После окончания сеанса связи, необходимо закрыть сокет, при этом серверу сообщается что сеанс связи закончен. Для закрытия сокета служит функция close, которой необходимо передать дескриптор сокета.
   
   
   
   
   close(SOCK);
   
   
   
   Ну и на последок пример рабочего кода. Программа соединяется с сервером www.perl.ru и забирает от туда главную страницу.
   
   
   
   
   use Socket;$host="www.perl.ru";$port="80";socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));$iaddr = inet_aton($host);$paddr = sockaddr_in($port, $iaddr);connect(SOCK, $paddr);send (SOCK, "GET / HTTP/1.0\n\n", 0);@data=&lt;SOCK&gt;;close(SOCK);print @data;
   
   
   
   Если вы попробуете поменять значения переменной $host, то обнаружите, что с некоторых серверов приходит сообщение об ошибке. Всему причиной HTTP протокол и настройки Web-серверов. Более подробно о HTTP читайте в статье "HTTP протокол". А пока о том как с этим бороться.
   
   Дело в том, что в сети существует очень большое количество виртуальных серверов, т.е. серверов с разными именами, но одним IP адресом. Попробуйте например сделать Ping Любое_имя.narod.ru. Все они будут иметь один IP адрес. А поскольку наш сокет фактически соединяется с IP адресом, то мы и получаем сообщение об ошибке. Web-сервер того же narod.ru просто не знает страницы какого из виртуальных серверов показывать. Значит нужно объяснить ему это. Для этого существует переменная HOST которая указывается в заголовке запроса. Т.е.
   
   
   
   
   send (SOCK, "GET / HTTP/1.0\nHOST:$host\n\n", 0);
   
   
   
   Подставив эту строчку в наш скрипт, мы получим уже более совершенную программу. Так же, некоторые сервера в зависимости от браузера (а вы еще не ощущаете себя им?) показывают разные версии сайтов. Встречается такое крайне редко, но к этому нужно быть готовым. Используйте для них переменную USER-AGENT.
   
   
   
   
   
   
   
   
   
   


<<НАЗАД      ОЦЕНИТЬ СТАТЬЮ    ВЕРСИЯ ДЛЯ ПЕЧАТИ>>
Статья прочитана :  раз.




пейкюлю



 
 
 
 
 
pauk ©® 2000-2015. All rights reserved.
При перепечатке ссылка на сайт и указание обязательны.
Мнение администрации сайта не всегда совпадает с мнением автора.
Орфография и пунктуация - авторские.
Администрация не несет никакой ответственности за использование материалов.
.
Protected by Copyscape DMCA Takedown Notice Infringement Search Tool