Основы PHP
  Что такое PHP?
  Возможности PHP
  Преимущества PHP
  История развития
  Что нового в PHP5?
  «Движок» PHP
  Переход на PHP 5.3
New Переход на PHP 5.6
  Введение в PHP
  Изучение PHP
  Основы CGI
  Синтаксис PHP
  Типы данных PHP
  Переменные в PHP
  Константы PHP
  Выражения PHP
  Операторы PHP
  Конструкции PHP
  Ссылки в PHP
  PHP и ООП
  Безопасность
  Функции PHP
  Функции по категориям
  Функции по алфавиту
  Стандартные функции
  Пользовательские
  PHP и HTTP
  Работа с формами
  PHP и Upload
  PHP и Cookies
  PHP и базы данных
  PHP и MySQL
  Документация MySQL
  Учебники
  Учебники по PHP
  Учебники по MySQL
  Другие учебники
  Уроки PHP
  Введение
  Самые основы
  Управление
  Функции
  Документация
  Математика
  Файлы
  Основы SQL
  Дата и время
  CURL
  Изображения
  Стили
  Безопасность
  Установка
  Проектирование БД
  Регулярные выражения
  Подготовка к работе
  Быстрый старт
  Установка PHP
  Установка MySQL
  Конфигурация PHP
  Download / Скачать
  Скачать Apache
  Скачать PHP
  Скачать PECL
  Скачать PEAR
  Скачать MySQL
  Редакторы PHP
  Полезные утилиты
  Документация
  PHP скрипты
  Скачать скрипты
  Инструменты
  PHP в примерах
  Новости портала
 Главная   »  Сборник статей
 
 

Использование сокетов в PHP

Автор: realcoding.net

PHP может открывать сокеты на локальной или удаленной машине. В данной статье будет рассмотрен пример использования сокетов для: соединения с Usenet-новостным сервером, ведения диалога с ним и скачивания некоторых статей.

Открываем сокет

Для открываения сокета используется функция fsockopen(). Вызов функции имеет следующий вид:

int fsockopen (string hostname, int port [, int errno [, string errstr [, double timeout]]])

Для UDP соединения, надо определить протокол: udp://hostname.

Больше информации о функции fsockopen() можно узнать здесь.

NNTP-протокол (Network News Transfer Protocol)

Для доступа к новостному usenet-серверу мы будем использовать NNTP-протокол.
Этот протокол детально описан в RFC977 (Request For Comment number 977). Полное описание присутствует в интернете: http://www.w3.org/Protocols/rfc977/rfc977.html
Этот документ детально описывает процедуру соединения и диалога с сервером.

Соединение (Connecting)

Для соединения с NNTP-сервером нам необходимо знать его имя (или IP-адрес) и порт. Так же необходимо указывать таймер, чтобы в случае невозможности подсоединения к серверу не “заморозили” application.

<?php

$cfgServer = "your.news.host";
$cfgPort = 119;
$cfgTimeOut = 10;

// open a socket
if(!$cfgTimeOut)
// without timeout
$usenet_handle = fsockopen($cfgServer, $cfgPort);
else
// with timeout
$usenet_handle = fsockopen($cfgServer, $cfgPort, &$errno, &$errstr, $cfgTimeOut);

if(!$usenet_handle) {
echo "Connexion failedn";
exit();
}
else {
echo "Connectedn";
$tmp = fgets($usenet_handle, 1024);
}

?>

Ведение диалога с сервером

Итак, теперь мы присоединились к серверу и можем вести диалог с ним, используя ранее открытый сокет. Для примера, попробуем достать десять последних сообщений с какой-либо группы. В RFC977 описано, что первый шаг – выбрать группу с помощью GROUP комманды:

GROUP ggg

Обязательный парамтор - ggg - имя группы, которую мы хотим выбрать (например, "net.news"). Список существующих групп может быть получен с помощью комманды LIST. Удачный выбор группы будет подтвержден ответом сервера, где будет сообщаться колличество новых, старых статей и общее колличество.

chrome:~$ telnet my.news.host 119
Trying aa.bb.cc.dd...
Connected to my.news.host.
Escape character is '^]'.
200 my.news.host InterNetNews NNRP server INN 2.2.2 13-Dec-1999 ready (posting ok).
GROUP alt.test
211 232 222996 223235 alt.test
quit
205

После получения команды "GROUP alt.test", новостной сервер ответил "211 232 222996 223235 alt.test". 211 – определенный RFC спецификацией код (говоря обычным языком – 212 – означает, что команда была завершена с положительным результатом – смотрите документацию RFC для более полной характеристики). Следующая цифра – 232 – количество имеющихся в текущий момент новых статей. 222996 – старых. 223235 – всего статей. 232+222996 не равно 223235. Почему? Возможно, недостающие семь статей были каким-либо образом удалены модератором или самим автором.

В зависимости от сервера (public или private) вас могут попросить идентифицироваться. Так-же возможно, что идентификация понадобиться только при написании своих сообщений, а чтение может производиться без этого.

<?php

//$cfgUser = "xxxxxx";
//$cfgPasswd = "yyyyyy";
$cfgNewsGroup = "alt.php";

// identification required on private server
if($cfgUser) {
fputs($usenet_handle, "AUTHINFO USER ".$cfgUser."n");
$tmp = fgets($usenet_handle, 1024);

fputs($usenet_handle, "AUTHINFO PASS ".$cfgPasswd."n");
$tmp = fgets($usenet_handle, 1024);

// check error

if($tmp != "281 Okrn") {
echo "502 Authentication errorn";
exit();
}
}

// select newsgroup

fputs($usenet_handle, "GROUP ".$cfgNewsGroup."n");
$tmp = fgets($usenet_handle, 1024);

if($tmp == "480 Authentication required for commandrn") {
echo "$tmpn";
exit();
}

$info = split(" ", $tmp);
$first = $info[2];
$last = $info[3];

print "First : $firstn";
print "Last : $lastn";

?>

Скачивание некоторых статей

Теперь мы имеем номер последней статьи, так что сейчас нам не составит труда скачать десять последних статей. RFC977 спецификация допускает использование команды ARTICLE, как с номером статьи, так и Message ID (Уникальный Номер Сообщения).
Будьте внимательны здесь – номер статьи отличен от Message ID. Если статья опубликована на нескольких серверах, то она несомненно будет иметь разный номер оба раза, но одинаковый Message ID. Грубо говоря, номер статьи – присваивается каждый раз по-новому на сервере, и может меняться со временем; Message ID – у каждой статьи уникальный.

<?php

$cfgLimit = 10;

// upload last articles

$boucle=$last-$cfgLimit;

while ($boucle <= $last) {

set_time_limit(0);

fputs($usenet_handle, "ARTICLE $bouclen");

$article="";
$tmp = fgets($usenet_handle, 4096);
if(substr($tmp,0,3) != "220") {
echo "+----------------------+n";
echo "Error on article $bouclen";
echo "+----------------------+n";
}
else {
while($tmp!=".rn") {
$tmp = fgets($usenet_handle, 4096);
$article = $article.$tmp;
}

echo "+----------------------+n";
echo "Article $bouclen";
echo "+----------------------+n";
echo "$articlen";
}

$boucle++;
}

?>

Также благодаря команде HEAD возможно получить только хэадер (header) сообщения или-же только текст, используя команду BODY.

Отсоединяемся от сервера

Чтобы закрыть сессию с NNTP-сервером, просто закройте сокет используя fclose() (аналогично закрытию файла).

Больше информации о функции fclose() можно узнать здесь.

<?php

// close connexion

fclose($usenet_handle);

?>

Заключение

Мы только что видели как открыть, использовать и затем закрыть сокет – для соединения с NNTP-сервером и получения некоторых статей из новостных групп.
Для опубликования сообщения необходимо использовать POST комманду.

Примеры приложений работующих с новостными группами можно найти здесь: http://www.phpindex.com/ng/

 
 » Обсудить эту статью на форуме

 
 Сборник статей 
 Содержание раздела 
Есть еще вопросы или что-то непонятно - добро пожаловать на наш  форум портала PHP.SU 
 

 
Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS