Pay attention! On some PHP version the MSG_DONTWAIT flag is not defined (see https://bugs.php.net/bug.php?id=48326)
socket_recvfrom
(PHP 4 >= 4.1.0, PHP 5)
socket_recvfrom — Recibe información desde un socket que esté o no orientado a conexión
Descripción
$socket
, string &$buf
, int $len
, int $flags
, string &$name
[, int &$port
] )
La función socket_recvfrom() recibe
len bytes de información en buf desde
name en el puerto port (si el
socket no es del tipo AF_UNIX) usando
socket. socket_recvfrom() se puede
usar para reunir información tanto desde socket conectados como de no conectados.
Además, se pueden especificar una o más banderas para modificar el comportamiento de
la función.
name y port deben ser
pasados por referencia. Si el socket no está orientado a conexión,
name será establecido a la dirección del protocolo de internet del
host remoto o a la ruta del socket UNIX. Si el socket está
orientado a conxión, name es NULL. Además,
port contendrá el puerto del host remoto en
el caso de un socket AF_INET o
AF_INET6 no conectado.
Parámetros
-
socket -
socketdebe ser un recurso socket previamente creado por socket_create(). -
buf -
La información recibida será recuperada a la variable especificada por
buf. -
len -
Se obtendrán hasta
lenbytes desde el host remoto. -
flags -
El valor de
flagspuede ser una combinación de las siguientes banderas, unidas con el operador binario OR (|).Valores posibles de flagsBandera Descripción MSG_OOBProcesar información fuera de banda. MSG_PEEKRecibir informaicón desde el inicio de la cola recibida sin eliminarla de la cola. MSG_WAITALLBloquea hasta que al menos se reciba lenbytes. Sin embargo, si se captura una señal o el host remoto se desconecta, la función puede devolver menos información.MSG_DONTWAITCon esta bandera establecida, la función devuelve incluso si normalmente habría bloqueado. -
name -
Si el socket es de tipo
AF_UNIX,namees la ruta del archivo. Por lo demás, para sockets no conectados,namees la dirección IP del host remoto, oNULLsi el socket está orientado a conexion. -
port -
Este argumento sólo se aplica a sockets
AF_INETyAF_INET6, y especifica el puerto remoto desde el que la información es recibida. Si el socket está orientado a conexión,portseráNULL.
Valores devueltos
socket_recvfrom() devuelve el número de bytes recibidos,
o FALSE si hubo un error. El código de error real se puede recuperar
llamando a socket_last_error(). Este código de error se puede
pasar a socket_strerror() para obtener una explicación textual
del error.
Ejemplos
Ejemplo #1 Un ejemplo de socket_recvfrom()
<?php
error_reporting(E_ALL | E_STRICT);
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '127.0.0.1', 1223);
$from = '';
$port = 0;
socket_recvfrom($socket, $buf, 12, 0, $from, $port);
echo "Se recibió $buf desde la dirección remota $from y el puerto remoto $port" . PHP_EOL;
?>
Este ejemplo iniciará un socket UDP en el puerto 1223 de 127.0.0.1 e imprimirá al menos 12 caracteres recibidos desde un host remoto.
Historial de cambios
| Versión | Descripción |
|---|---|
| 4.3.0 | socket_recvfrom() ahora es segura a nivel binario. |
Ver también
- socket_recv() - REcibe información desde un socket conectado
- socket_send() - Envía información a un socket conectado
- socket_sendto() - Envía un mensaje a un socket, ya esté conectado o no
- socket_create() - Crear un socket (extremo de comunicación)
DNS RELAY USING UDP SOCKETS
<?php
while(TRUE) {
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
if($socket === FALSE)
{
echo 'Socket_create failed: '.socket_strerror(socket_last_error())."\n";
}
if(!socket_bind($socketD, "0.0.0.0", 53)) {
socket_close($socketD);
echo 'socket_bind failed: '.socket_strerror(socket_last_error())."\n";
}
socket_recvfrom($socket,$buf,65535,0,$clientIP,$clientPort);
$stz = bin2hex($buf);
$tx = "";
for($i=0;$i<(strlen($stz)-26-10)/2;$i++)
{
$e = "00";
$e[0] = $stz[$i*2+26];
$e[1] = $stz[$i*2+27];
$f = hexdec($e);
if($f > 0 && $f < 32) $tx .= "."; else
$tx .= sprintf("%c",$f);
}
echo "$clientIP <".$tx.">\n";
$fp = fsockopen("udp://72.174.110.4",53,$errno,$errstr);
if (!$fp)
{
echo "ERROR: $errno - $errstr<br />\n";
}
else
{
fwrite($fp,$buf);
$ret = $buf;
$ret = fread($fp,667);
fclose($fp);
}
}
socket_send($socket,$ret,667,0);
}
?>
I'm confused about the rerturn value of socket_recvfrom(), it said -1 when failed, but when I call like this:
if (($len = @socket_recvfrom($sock, $result, 32, 0, $ip, $port)) == -1) {
if ($this->_debug) {
echo "socket_read() failed: " . socket_strerror(socket_last_error()) . "\n";
}
return false;
}
variable $len = false, when I change the buffer length from 32 to 4096, it becomes right.
This function is very handy when dealing with UDP connections, because it enables you to know who's the client who connected to your socket. Bear in mind that UDP doesn't care about the source of the connection, the packets may be annonymous or even faked. No check is required.
If you want to listen on an UDP socket and answer to the client, read my comment on socket_listen() -> http://www.php.net/manual/en/function.socket-listen.php
