stream_socket_recvfrom

(PHP 5, PHP 7, PHP 8)

stream_socket_recvfromRecebe dados de um socket, conectado ou não

Descrição

stream_socket_recvfrom(
    resource $socket,
    int $length,
    int $flags = 0,
    ?string &$address = null
): string|false

stream_socket_recvfrom() aceita dados de um socket remoto até a quantidade de bytes definida por length.

Parâmetros

socket

O socket remoto.

length

O número de bytes a receber do socket.

flags

O valor de flags pode ser qualquer combinação das opções a seguir:

Valores possíveis para flags
STREAM_OOB Processa dados fora-de-banda (do inglês OOB out-of-band).
STREAM_PEEK Recebe dados do socket, mas não consome o buffer. Chamadas subsequentes a fread() ou stream_socket_recvfrom() irão ver os mesmos dados.

address

Se address for fornecido, será preenchido com o endereço do socket remoto.

Valor Retornado

Retorna os dados lidos, como uma string, ou false em caso de falha.

Exemplos

Exemplo #1 Exemplo de stream_socket_recvfrom()

<?php
/* Abre um socket de servidor na porta 1234 no servidor local */
$server = stream_socket_server('tcp://127.0.0.1:1234');

/* Aceita uma conexão */
$socket = stream_socket_accept($server);

/* Pega um pacote (1500 é um tamanho típico de MTU) de dados OOB */
echo "Recebido Out-Of-Band: '" . stream_socket_recvfrom($socket, 1500, STREAM_OOB) . "'\n";

/* Dá uma olhada nos dados normais dentro-da-banda, mas não os consome. */
echo "Dados: '" . stream_socket_recvfrom($socket, 1500, STREAM_PEEK) . "'\n";

/* Obtém o mesmo pacote novamente, mas remove-o do buffer desta vez. */
echo "Dados: '" . stream_socket_recvfrom($socket, 1500) . "'\n";

/* Fecha tudo */
fclose($socket);
fclose($server);
?>

Notas

Nota:

Se uma mensagem recebida for maior que o parâmetro length, os bytes excedentes podem ser descartados dependendo do tipo do socket do qual a mensagem for recebida (como no UDP).

Nota:

Chamadas a stream_socket_recvfrom() em fluxos baseados em socket, depois de chamadas a funções de fluxo baseadas em buffer (como fread() ou stream_get_line()) lêem dados diretamente do socket e ignoram o buffer de fluxo.

Veja Também

add a note add a note

User Contributed Notes 3 notes

up
17
cweiske at php dot net
14 years ago
Note that stream_socket_recvfrom() bypasses stream wrappers including TLS/SSL. While reading from an encrypted stream with fread() will return decrypted data, using stream_socket_recvfrom() will give you the original encrypted bytes.
up
4
MagicalTux at php dot net
13 years ago
This method may return a peer address not compatible with stream_socket_sendto() if in ipv6.

The ip returned by recvfrom is not within brackets ([]), and has the port appended, which makes it look like ::1:1234. To cut it properly, use strrpos()
up
1
raat1979 at gmail dot com
9 years ago
Basically there is currently no real way to determine what the position of the Out of band data is in the tcp/ip stream.

However, it seems that In my current environment (winsock: Windows / PHP 5.3.0) you do not peek beyond the OOB byte unless the buffer is empty
reads do read beyond the OOB data. (I'll check my linux box later)

You should be able to figure out the position of the OOB data by peeking and reading from the regular stream
although it would not be 100% reliable as we do read beyond the OOB data when nothing is in front of it.
depending on the high level protocol it might be possible
to handle the specific "no data in front of out-of-band data" case

<?php
echo "<pre>";
$sockets = stream_socket_pair(STREAM_PF_INET, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$reader=$sockets[0];
$writer=$sockets[1];

stream_socket_sendto($writer,"abc");
stream_socket_sendto($writer,"xyZ",STREAM_OOB); // ONLY THE LAST BYTE IS MARKED AS OOB DATA
stream_socket_sendto($writer,"def");

echo
"\r\n";
echo
"Test 1, Peeking beyond oob when the read buffer becomes empty\r\n";
echo
"The data order is 'abcxyZdef'\r\n";
stream_select($r=array($reader), $w=array(), $x=array($reader),5);
echo
"has regular:";var_dump(count($r)!==0);
echo
"has oobData:";var_dump(count($x)!==0);
echo
"<span style='color:blue' >Peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";
echo
"<span style='color:green'>Peek (1) OobData:".stream_socket_recvfrom($reader,9,STREAM_OOB|STREAM_PEEK)."</span>\r\n";
echo
"<span style='color:black'>READ (4) regular:".stream_socket_recvfrom($reader,4)."</span>\r\n";
echo
"<span style='color:blue' >Peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";
echo
"<span style='color:black'>READ (1) regular:".stream_socket_recvfrom($reader,1)."</span>\r\n";
echo
"<span style='color:blue' >Peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";
// read the OOB data
echo "<span style='color:red'  >READ (9) OobData:".stream_socket_recvfrom($reader,9,STREAM_OOB)."</span>\r\n";

echo
"<span style='color:blue' >Peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";

fclose($sockets[0]);
fclose($sockets[1]);
echo
"</pre>";
?>
outputs:
Test 1, Peeking beyond oob when the read buffer becomes empty
The data order is 'abcxyZdef'
has regular:bool(true)
has oobData:bool(true)
Peek (9) regular:abcxy
Peek (1) OobData:Z
READ (4) regular:abcx
Peek (9) regular:y
READ (1) regular:y
Peek (9) regular:def
READ (9) OobData:Z
Peek (9) regular:def

<?php
echo "<pre>";
$sockets = stream_socket_pair(STREAM_PF_INET, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$reader=$sockets[0];
$writer=$sockets[1];

stream_socket_sendto($writer,"Z",STREAM_OOB); // ONLY THE LAST BYTE IS MARKED AS OOB DATA
stream_socket_sendto($writer,"abcxydef");

echo
"<hr/>";
echo
"\r\n";
echo
"Test 2, peek if there is nothing in front of the OOB data\r\n";
echo
"The data order is 'Zabcxydef'\r\n";
stream_select($r=array($reader), $w=array(), $x=array($reader),5);
echo
"has regular:";var_dump(count($r)!==0);
echo
"has oobData:";var_dump(count($x)!==0);
echo
"<span style='color:blue'>peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";
echo
"<span style='color:red' >Peek (9) OobData:".stream_socket_recvfrom($reader,9,STREAM_OOB)."</span>\r\n";
echo
"<span style='color:blue'>peek (9) regular:".stream_socket_recvfrom($reader,9,STREAM_PEEK)."</span>\r\n";
echo
"</pre>";
?>
Outputs:
Test 2, peek if there is nothing in front of the OOB data
The data order is 'Zabcxydef'
has regular:bool(true)
has oobData:bool(true)
peek (9) regular:abcxydef
Peek (9) OobData:Z
peek (9) regular:abcxydef
To Top