Низкоуровневый сетевой (сокет) интерфейс
Файлы и сети
🕛 01.11.2006, 13:29
Эта группа функций позволяет использовать низкоуровневый сетевой интерфейс и выступать как в качестве сервера, так и в качестве клиента. Для возможности их использования они должны быть разрешены при компиляции директивой -enable-sockets. Подразумевается, что вы имеете представление о том, как функционирует этот интерфейс на уровне системы. Наиболее общий сетевой интерфейс предоставляют сокет-функции fsockopen() и pfsockopen() (их проще использовать в том случае, если вам не требуется создание сервера).
Пример 1. Простой TCP/IP сервер
Этот пример иллюстрирует реализацию простого сервера, отвечающего на запросы. Измените адрес и порт по вашему усмотрению. Подключиться к этому серверу можно с помощью сетевого клиента, например командой: telnet 192.168.1.53 10000 (параметры: ваш адрес и используемый порт). Все, что будет посылаться на сервер, будет на нем выводиться и возвращаться эхом клиенту. Для прекращения сеанса связи введите 'quit'.
<?php
error reporting (E_ALL);
/* Позволяет сценарию бесконечно
удерживать связь. */ setjnmejimit (0):
Saddress = '192.168.1 53';
/* установите свои значения
*/ Sport = 10000:
if (($sock = socket
(AFJNET. SOCK_STREAM. 0)) < 0)
{ echo " Ошибка в socketO: "
. strerror (Ssock) . "\n": }
if (($ret = bind (Ssock. Saddress. Sport))
< 0) { echo "Ошибка в bind()
. " strerror ($ret) "\n"; )
if ((Sret = listen (Ssock. 5)) < 0)
{ echo "Ошибка в listen(): "
. strerror (Sret) . "\n"; }
do ( if ((Smsgsock = accept_connect
($sock)) < 0) { echo
"Ошибка в accept_connect().
". strerror (Smsgsock)."\n" break;
} do { $buf = " ;
Sret = read (Smsgsock. Sbuf. 2048):
if (Sret < 0) {
echo "Ошибка в read(): " strerror (Sret) .
"\n": break 2; }
if (Sret == 0) { break 2. }
Sbuf = trim (Sbuf):
if ($buf == 'quit') {
close (Smsgsock);
break 2: } Stalkback = "Вы ввели
'Sbuf'.W: write (Smsgsock. Stalkback,
strlen (Stalkback)); echo "Sbuf\n": }
while (TRUE): close (Smsgsock). }
while (TRUE). close (Ssock); ?>
Пример 2. Простой TCP/IP клиент
Данный сценарий получает страницу через HTTP, отправляет запрос HEAD, выводит ответ и завершается.
<?php
error_reporting (E_ALL);
echo "<h2>TCP/IP Connection</h2>\n";
/* Получить порт службы WWW
(обычно: 80). */ $service_port =
getservbyrame ('www'. 'tcp'):
'* Попучить IP адрес хоста */
Saddress = gethostbyname
Cwww.php.net'):
/* Создать TCP/IP socket. */
Ssocket - socket (AFJNET. SOCK_SlRtAM. 0):
if (Ssocket < 0) {
echo "Ошибка в socketO:
" strerror (Ssocket) . "\n": }
else { "socket создан " strerror (Ssocket) .
"\n", }
echo "Попытка подключиться
к '$address' (порт 'Sservice_port')
..."; Sresult = connect
(Ssocket. Saddress. $servKe_port);
if (Sresjit 0) { echo "Ошибка в
connect;): ($result) " strerror(Sresult)
."\n"; } else { echo "OK \r". }
$111 = "HFAD / HTTP/1.0\r\rur\n";
// посылаемые данные $out = '':
// буфер для приема данных
echo "Sending HTTP HEAD request...":
// послать запрос заголовка HTTP
write (Ssocket. $in, strlen ($in)). echo "GKAn":
echo "Reading response:\n\n":
// принять ОТВEТ (заголовок) while
(read (Ssocket. Sout. 2048))
{ echo Sout: } echo "closing
socket..."; close (Ssocket):
echo "OK.\n\n": ?>
socket
Создание сокета
int socket (int domain, int type, int protocol)
Создаст конечную точку сетевой коммуникации (сокет) и возвращает его дескриптор. При ошибке возвращает отрицательное значение кода ошибки, которое затем может быть передано в функцию strerror() для получения текстового объяснения причины ошибки.
Аргументом domain указывается тин сети, в которой создастся сокет; %. допустимые значения: AF JNET и AF_UNIX.
Аргумент type указывает тип создаваемого сокета; он может быть одним из следующих: SOCK_STREAM, SOCKJDGRAM, SOCKJEQPACKET, SOCK_RAW, SOCK RDM или SOCK PACKET.
Аргумент protocol определяет используемый протокол передачи данных.
Более подробная информация содержится в системной документации.
См. также: accept_connect(), bind(), connect(), listen(), strerror() и socket_get_status().
close
Закрытие сокета
bool close (int socket)
Закрывает сокет, указанный дескриптором, и возвращает TRUE или FALSE (при ошибке или при недопустимом дескрипторе).
Заметьте: функция не может использоваться с файловыми дескрипторами РНР, созданными fopen(), popen(), fsockopen(), psockopen(); она работает только с теми, которые созданы функциями socket() или accept_connect().
См. также: bind(), listen(), socket(), socket_get_status() и strerror().
connect
Подключение к сокету
int connect (int socket, string address [, int port])
Инициирует подключение, используя дескриптор socket (который должен быть ранее успешно создан функцией socket()). Возвращает О или, при ошибке, отрицательное значение кода ошибки, которое затем может быть передано в функцию strerror() для получения текстового объяснения причины ошибки.
Аргумент address должен содержать либо адрес IP, в формате с разделением точками (например: 127.0.0.1), если socket принадлежит семейству AF_INET; либо строку пути к соксту в домене Unix, если он из семейства AFJJNIX.
Аргумент port используется только для AF_INET сокет и определяет порт удаленной машины, к которому производится подключение.
См. также: bind(), listen(), socket(), socket_get_status() и strerror().
bind
Привязка сокета к адресу
int bind (int socket, string address [. int port])
Назначает socket (который должен быть ранее успешно создан функ-дней socket()) IP-адресу address. Возвращает 0 или, при ошибке, от-рнцатсльное значение кода ошибки, которое затем может быть передано в функцию strerror() для получения текстового объяснения причины ошибки.
Аргумент должен содержать либо адрес IP, в формате с разделением точками (например: 127.0.0.1), если сокет принадлежит семейству AF_INET; либо строку пути к,сокету и домене Unix, если он из семейства AFJJNIX.
Аргумент port используется только для AF_INET сокет и определяет порт удаленной машины, к которому производится подключение.
Заметьте: для подключения (в качестве клиента) используется функция connect(), эта же функция позволяет выступать в роли сервера (для этого дополнительно используются функции accept_connect() и listen()).
См. также: accept_connect(), connect(), listen(), socket(), socket_get_ status() и strerror().
listen
Разрешение приема данных из сокета
int listen (int socket, int backlog)
После того как функцией socket() создан сокет и он назначен адресу (его порту) функцией bind(), эта функция позволяет системе ожидать получения внешних данных и перенаправлять их в socket. Аргумент backlog указывает максимальное число входящих и воспринимаемых подключений.
Функция применима только к типам сокетов: SOCK_STREAM или SOCK SEQPACKET.
Возвращает 0 или, при ошибке, отрицательное значение кода ошибки, которое затем может быть передано в функцию strerror() для получения текстового объяснения причины ошибки.
См. также: accept_connect(), bind(), connect(), socket(), socket_get_status() и strerror().
accept_ connect
Прием данных от сокета
int accept connect (int socket)
После того как функцией socket() создан сокет, и он был назначен адресу (его порту) функцией bind(), и функцией listen() было разрешено принимать входящие подключения; эта функция указывает системе принимать внешние данные из socket.
Возвращает новый сокет-дескриптдр или, при ошибке, отрицательное значение кода ошибки, которое затем может быть передано в функцию strerror() для получения текстового объяснения причины ошибки. Возвращаемый дескриптор используется исключительно для обмена данными с клиентами подключений. Исходный дескриптор тем не менее остается действительным и может использоваться.
При появлении нескольких входящих подключений используется первое; при их отсутствии функция будет ожидать их появления. Если socket был разблокирован функцией socket_set_blocking() (или set_ nonblockO), при отсутствии входящих данных функция завершается с соответствующим кодом ошибки.
См. также: bind(), connect(), listen(), socket(), socket_get_status() и strerror().
read
Получение данных от сокета
int read (int socket_des, string Sbuffer, int length)
Функция читает данные из socketjies (сокет-дсскриптор, «воссозданный» функцией accept_connect()) в буфер Sbuffer, в объеме байтов, указанном length. Чтение завершается ранее, если встречается символ <<\n», <<\t» или «\0». Возвращает число прочитанных байтов.
См. также: accept_connect(), bind(), connect(), listen(), strerror(), socket_get status() и write().
write
Запись данных в сокет
int write (int socket_des, string Sbuffer, int length)
Записывает в сокет socketjjes содержимое буфера Sbuffer в объеме length байтов.
См. также: accept_connect(), bind(), connect(), listen(), read(), strerror() и socket_get_status().
strerror
Получение описания ошибки сокета
string strerror (int errno)
Принимаемый аргумент errno является значением, возвращаемым одной из сокет-функций. Возвращается строка текста, объясняющая код ошибки. Это делает более удобным разбор причин неработоспособности.
<?php
if (($socket = socket (AFJNET,
SOCK_STREAM. 0)) < 0) {
echo "Причина ошибки в socket():
" . strerror (Ssocket) . "\n": }
if (($ret = bind ($socket. '127.0.0.1'. 80)) < 0)
{ echo "Причина ошибки в bind():
" . strerror ($ret) . "\n": } ?>
Если указанный сценарий будет исполняться не с административными привилегиями (root), то скорее всего он выведет: «Причина ошибки в bind(): Permission denied».
См. также: accept_connect(), bind(), connect(), listen(), socket() и socket_ get_status().