stream_socket_client

(PHP 5, PHP 7)

stream_socket_clientОткрывает соединение с интернет-сокетом или с доменным сокетом Unix

Описание

resource stream_socket_client ( string $remote_socket [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") [, int $flags = STREAM_CLIENT_CONNECT [, resource $context ]]]]] )

Начинает потоковое или датаграммное соединение с удалённым сокетом, указанным параметром remote_socket. Тип создаваемого сокета определяется по транспорту, указанному с использованием стандартного форматирования URL: transport://target. Для интернет-сокетов, (AF_INET) таких, как TCP и UDP, часть target параметра remote_socket должна состоять из имени хоста или IP-адреса, за которым следует двоеточие и номер порта. Для доменных сокетов Unix, часть target должна указывать на файл сокета в файловой системе.

Замечание:

По умолчанию поток будет открыт в блокирующем режиме. Вы можете переключить его в неблокирующий режим, используя функцию stream_set_blocking().

Список параметров

remote_socket

Адрес удалённого сокета для соединения.

errno

Будет присвоен номер системной ошибки, если соединение не удалось установить.

errstr

Будет присвоено сообщение о системной ошибке, если соединение не удалось установить.

timeout

Число секунд, в течение которых должен произойти тайм-аут системного вызова connect().

Замечание: Этот параметр применяется только если не происходит попытка асинхронного соединения.

Замечание:

Чтобы указать тайм-аут для чтения/записи данных через сокет, используйте функцию stream_set_timeout(), так как параметр timeout применяется только при создании соединения через сокет.

flags

Поле битовой маски, которое может принимать значение любой комбинации флагов соединения. В настоящее время набор флагов соединения ограничен следующими значениями STREAM_CLIENT_CONNECT (по умолчанию), STREAM_CLIENT_ASYNC_CONNECT и STREAM_CLIENT_PERSISTENT.

context

Действующий ресурс контекста, созданный при помощи функции stream_context_create().

Возвращаемые значения

В случае успеха возвращается ресурс потока, который может быть использован с другими файловыми функциями (такими, как fgets(), fgetss(), fwrite(), fclose(), и feof()), в случае неудачи возвращается FALSE.

Ошибки

В случае неудачного вызова функции аргументы errno и errstr будут заполнены системной ошибкой, которая произошла при системном вызове connect(). Если значение, возвращённое в аргументе errno равно 0 и функция возвратила значение FALSE, это означает, что ошибка произошла до вызова connect(). Это произошло скорее всего из-за проблемы инициализации сокета. Примите во внимание, что аргументы errno и errstr всегда будут передаваться по ссылке.

Примеры

Пример #1 Пример использования функции stream_socket_client()

<?php
$fp 
stream_socket_client("tcp://www.example.com:80"$errno$errstr30);
if (!
$fp) {
    echo 
"$errstr ($errno)<br />\n";
} else {
    
fwrite($fp"GET / HTTP/1.0\r\nHost: www.example.com\r\nAccept: */*\r\n\r\n");
    while (!
feof($fp)) {
        echo 
fgets($fp1024);
    }
    
fclose($fp);
}
?>

Пример #2 Использование UDP-соединения

Получения дня и времени от UDP-сервиса "daytime" (порт 13) на localhost.

<?php
$fp 
stream_socket_client("udp://127.0.0.1:13"$errno$errstr);
if (!
$fp) {
    echo 
"ОШИБКА: $errno - $errstr<br />\n";
} else {
    
fwrite($fp"\n");
    echo 
fread($fp26);
    
fclose($fp);
}
?>

Примечания

Внимание

UDP-сокеты иногда могут открываться без ошибки, даже если удалённый хост недоступен. Ошибка станет заметной только когда вы будете читать или писать данные из/в сокет. Причина этого в том, что UDP - это протокол без соединения, что означает, что операционная система не пытается установить соединение с сокетом до тех пор, пока ей в действительности не нужно отправить или получить данные.

Замечание: При указании числового адреса IPv6 (например, fe80::1) вы должны заключать его в квадратные скобки. Например, tcp://[fe80::1]:80.

Замечание:

В зависимости от окружения, Unix-домены или произвольный таймаут соединения могут быть недоступны. Список доступных транспортов может быть получен используя функцию stream_get_transports(). Смотрите список встроенных транспортов на странице Список поддерживаемых транспортных протоколов.

Смотрите также

  • stream_socket_server() - Создаёт интернет-сокет или доменный сокет Unix
  • stream_set_blocking() - Устанавливает блокирующий/неблокирующий режим на потоке
  • stream_set_timeout() - Устанавливает значение тайм-аута на потоке
  • stream_select() - Запускает эквивалент системного вызова select() на заданных массивах потоков с таймаутом, указанным параметрами tv_sec и tv_usec
  • fgets() - Читает строку из файла
  • fgetss() - Прочитать строку из файла и отбросить HTML-теги
  • fwrite() - Бинарно-безопасная запись в файл
  • fclose() - Закрывает открытый дескриптор файла
  • feof() - Проверяет, достигнут ли конец файла
  • cURL

Коментарии

# Some may find it useful to know that your caCert 
# must be in pem format, and that PHP seems to like 
# your key, cert, and cacert pem's to be concatenated
# in a single file (I suffered various "unknown chain" 
# errors, otherwise)
#
# So, (linux users), concat your components as follows:
# (where current working dir is dir where 
# cert components are stored)
#
# cat key.pem >certchain.pem
# cat cert.pem >>certchain.pem
# cat cacert.pem >>certchain.pem
#
# Then, the php....
##################################

<?php

$host 
'host.domain.tld';
$port 1234;
$timeout 10;

$cert '/path/to/your/certchain/certchain.pem';
$context stream_context_create(array('ssl'=>array('local_cert'=> $cert,
)));

if (
$fp stream_socket_client('ssl://'.$host.':'.$port$errno$errstr30,
       
STREAM_CLIENT_CONNECT$context)) {
   
fwrite($fp"\n");
    echo 
fread($fp,8192);
   
fclose($fp);
} else {
   echo 
"ERROR: $errno - $errstr<br />\n";
}

?>
2007-08-31 17:06:30
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html
I came here since fsockopen() does not support any SSL certificate checking in PHP5.

while curl is nice, I use stream_socket_client() to make XML-RPC POST requests via HTTPS and since I have not found any PHP code around that does this, I'll attach an example that also includes HTTP-Digest Auth (eg. trac's WikiRPCInterface2):

<?php
#################################################
# $host: hostname ; eg 'example.org' 
# $path: request' eg '/index.php?id=123'
# $data_to_send : data to POST after the HTTP header.
#
# if $opts is an  empty array() a standard  HTTP to port 80 request is performed. 

# set auth['type']='basic' to use plain-text auth, 
# digest-auth will be handled automatically if $auth['username'] is set and a 401
# status is encountered. - use auth['type']='nodigest' to override.
#
##
function httpPost($host$path$data_to_send,
                 
$opts=array('cert'=>""'headers'=>0'transport' =>'ssl''port'=>443),
                 
$auth=array('username'=>""'password'=>""'type'=>"")
                 ) {
 
$transport=''$port=80;
  if (!empty(
$opts['transport'])) $transport=$opts['transport'];
  if (!empty(
$opts['port'])) $port=$opts['port'];
 
$remote=$transport.'://'.$host.':'.$port;

 
$context stream_context_create();
 
$result stream_context_set_option($context'ssl''verify_host'true);
  if (!empty(
$opts['cert'])) {
   
$result stream_context_set_option($context'ssl''cafile'$opts['cert']);
   
$result stream_context_set_option($context'ssl''verify_peer'true);
  } else {
   
$result stream_context_set_option($context'ssl''allow_self_signed'true);
  }
 
$fp stream_socket_client($remote$err$errstr60STREAM_CLIENT_CONNECT$context);

  if (!
$fp) {
   
trigger_error('httpPost error: '.$errstr);
    return 
NULL;
  }

 
$req='';
 
$req.="POST $path HTTP/1.1\r\n";
 
$req.="Host: $host\r\n";
  if (
$auth['type']=='basic' && !empty($auth['username'])) {
   
$req.="Authorization: Basic ";
   
$req.=base64_encode($auth['username'].':'.$auth['password'])."\r\n";
  }
  elseif (
$auth['type']=='digest' && !empty($auth['username'])) {
   
$req.='Authorization: Digest ';
    foreach (
$auth as $k => $v) {
      if (empty(
$k) || empty($v)) continue;
      if (
$k=='password') continue;
     
$req.=$k.'="'.$v.'", ';
    }
   
$req.="\r\n";
  }
 
$req.="Content-type: text/xml\r\n";
 
$req.='Content-length: 'strlen($data_to_send) ."\r\n";
 
$req.="Connection: close\r\n\r\n";

 
fputs($fp$req);
 
fputs($fp$data_to_send);

  while(!
feof($fp)) { $res .= fgets($fp128); }
 
fclose($fp);

  if (
$auth['type']!='nodigest'
       
&& !empty($auth['username'])
        && 
$auth['type']!='digest' # prev. digest AUTH failed.
       
&& preg_match("/^HTTP\/[0-9\.]* 401 /"$res)) {
    if (
== preg_match("/WWW-Authenticate: Digest ([^\n\r]*)\r\n/Us"$res$matches)) {
      foreach (
split(","$matches[1]) as $i) {
       
$ii=split("=",trim($i),2);
        if (!empty(
$ii[1]) && !empty($ii[0])) {
         
$auth[$ii[0]]=preg_replace("/^\"/",''preg_replace("/\"$/",''$ii[1]));
        }
      }
     
$auth['type']='digest';
     
$auth['uri']='https://'.$host.$path;
     
$auth['cnonce']=randomNonce();
     
$auth['nc']=1;
     
$a1=md5($auth['username'].':'.$auth['realm'].':'.$auth['password']);
     
$a2=md5('POST'.':'.$auth['uri']);
     
$auth['response']=md5($a1.':'
                           
.$auth['nonce'].':'.$auth['nc'].':'
                           
.$auth['cnonce'].':'.$auth['qop'].':'.$a2);
      return 
httpPost($host$path$data_to_send$opts$auth);
    }
  }

  if (
!= preg_match("/^HTTP\/[0-9\.]* ([0-9]{3}) ([^\r\n]*)/"$res$matches)) {
   
trigger_error('httpPost: invalid HTTP reply.');
    return 
NULL;
  }

  if (
$matches[1] != '200') {
   
trigger_error('httpPost: HTTP error: '.$matches[1].' '.$matches[2]);
    return 
NULL;
  }

  if (!
$opts['headers']) {
   
$res=preg_replace("/^.*\r\n\r\n/Us",'',$res);
  }
  return 
$res;
}
?>
2008-08-26 18:34:21
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html
For those wanting to use stream_socket_client() to connect to a local UNIX socket who can't find documentation on how to do it, here's a (rough) example:

<?php

$sock 
stream_socket_client('unix:///full/path/to/my/socket.sock'$errno$errstr);

fwrite($sock'SOME COMMAND'."\r\n");

echo 
fread($sock4096)."\n";

fclose($sock);

?>
2008-10-28 19:08:50
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html
stream_socket_client is much easier and faster to use to direct sockets, because you can use directly fwrite / fget / fclose functions, but I find hard to find how to connect to a UNIX domain socket. The URL to use is "udg:///path/to/socket".

For example, to log to the log socket (like syslog), you can use:

<?php
$socket 
stream_socket_client('udg:///dev/log',
       
$errorno,
       
$errorstr,
       
$timeout);
fwrite($socket, ...);
?>
2010-03-29 12:04:28
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html
The remote_socket argument, in its end (well... after the port), can also contain a "/" followed by a unique identifier. This is especially useful if you want to create multiple persistent connections to the same transport://host:port combo.

Example:
<?php
$socket 
stream_socket_client('tcp://mysql.example.com:3306/root'$errorno$errorstr$timeoutSTREAM_CLIENT_CONNECT STREAM_CLIENT_PERSISTENT);
?>

Note that while (p)fsockopen() follows a similar scheme, it doesn't have this particular feature.
2011-08-14 16:11:50
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html
Автор:
If you only need to check a stream for data, you can use stream_get_content and strtr function. stream_get_content 
reads the remainder of a stream into a string. 
<?php

$addr 
gethostbyname('www.example.com');

$client stream_socket_client("tcp://$addr:80"$errno$errorMessage);

 if(
$client === false){
                throw new 
UnexpectedValueException("Failed to connect: $errorMessage");
        }
       
       
fwrite($client"GET / HTTP/1.0\r\nhost:    'www.example.com'\r\nAccept: */*\r\n\r\n");
       
$variable stream_get_content($client);

if(
strstr($variable,'data your looking for'))
       echo 
"The data you are looking for is here";
else
       echo 
"data not found";

fclose($client);
?>
2014-09-12 23:29:43
http://php5.kiev.ua/manual/ru/function.stream-socket-client.html

    Поддержать сайт на родительском проекте КГБ