PHP 8.3.4 Released!

socket_recvfrom

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

socket_recvfrom从套接字接收数据,无论它是否是面向连接的

说明

socket_recvfrom(
    Socket $socket,
    string &$data,
    int $length,
    int $flags,
    string &$address,
    int &$port = null
): int|false

函数 socket_recvfrom() 使用 socketaddressport 端口上接收 length 字节数据到 data 中(如果套接字不是 AF_UNIX 类型)。socket_recvfrom() 可用于从已连接或未连接的套接字上收集数据。另外,可以指定一个或多个标志来修改函数的行为。

addressport 必须是引用传递。如果套接字不是面向连接的,address 将设置为远程主机的互联网协议地址或 UNIX 套接字路径。如果套接字是面向连接的,addressnull。另外,在 AF_INETAF_INET6 套接字未连接的情况下,port 将包含远程主机的端口号。

注意: 此函数可安全用于二进制对象。

参数

socket

socket 必须是先前由 socket_create() 创建的 Socket 实例。

data

收到的数据将提取到 data 指定的变量。

length

最多可从远程主机获取的 length 字节数。

flags

flags 的值可以是下列任意 flag 的组合。使用按位或运算符(|)来组合不同的 flag。

flags 可用值
Flag 描述
MSG_OOB 处理带外数据。
MSG_PEEK 从接收队列的起始位置接收数据,但不将他们从接收队列中移除。
MSG_WAITALL 在接受到至少 length 字节数据前阻塞。但是,如果接收到中断信号,或远程主机断开链接,函数可能返回不足 length 字节的数据。
MSG_DONTWAIT 如果指定了该 flag,即使原有套接字是阻塞的,此函数也不会阻塞。
address

如果套接字是 AF_UNIX 类型,address 是文件路径。否则,对于未连接的套接字,address 是远程主机的 IP 地址,如果套接字是面向连接的,是 null

port

此参数只适用于 AF_INETAF_INET6 类型的套接字,并指定接收数据的远程端口。如果套接字是面向连接的,portnull

返回值

socket_recvfrom() 返回接收到的字节数,发生错误时返回 false。可以通过调用 socket_last_error() 来检索实际的错误代码。此错误码可以传递给 socket_strerror() 获得错误的文本解释。

更新日志

版本 说明
8.0.0 现在 socketSocket 实例, 之前是 resource

示例

示例 #1 socket_recvfrom() 示例

<?php

$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
"Received $buf from remote address $from and remote port $port" . PHP_EOL;
?>

此示例将在 127.0.0.1 的 1233 端口上初始化 UDP 套接字,并打印从远程主机收到的至少 12 个字符。

参见

add a note

User Contributed Notes 5 notes

up
3
lorin dot weilenmann at gmail dot com
8 years ago
If you use socket_recvfrom on a UDP socket and combine it with the MSG_DONTWAIT flag, it will raise a PHP Warning if there is nothing to read. AFAIK, there is no way around that warning except suppressing it with @ (i.e. you cannot check if there is data before calling socket_recvfrom).
up
1
ply2attoetensen-project.com
7 years ago
MSG_DONTWAIT doesn't seem to exist in windows sockets. However socket_set_nonblock() seems to do the trick.
up
1
davide dot renzi at gmail dot com
12 years ago
Pay attention! On some PHP version the MSG_DONTWAIT flag is not defined (see https://bugs.php.net/bug.php?id=48326)
up
-3
jaggerwang at gmail dot com
16 years ago
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.
up
-13
ryan_at_ryanfisher_dot_com
17 years ago
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);
}
?>
To Top