多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
**socket_recvfrom** ( resource **$socket** , string **&$buf** , int **$len** , int **$flags** , string **&$name** [, int **&$port** ] ) : int — 从套接字接收数据,无论它是否面向连接 使用套接字从端口端口上的名称(如果套接字不是AF_UNIX类型)接收buf中的len字节数据。 socket_recvfrom()可用于从已连接和未连接的套接字收集数据。 此外,可以指定一个或多个标志来修改功能的行为 名称和端口必须通过引用传递。 如果套接字不是面向连接的,则名称将设置为远程主机的Internet协议地址或UNIX套接字的路径。 如果套接字是面向连接的,则名称为NULL。 此外,如果未连接AF_INET或AF_INET6套接字,则该端口将包含远程主机的端口 返回接收到的字节数,如果有错误则返回FALSE。 可以通过调用socket_last_error()来检索实际的错误代码。 该错误代码可以传递给socket_strerror()以获得错误的文本说明 参数: socket 套接字必须是先前由socket_create()创建的套接字资源。 buf 接收到的数据将被提取到buf指定的变量中。 len 从远程主机最多可以提取len个字节。 flags 标志的值可以是以下标志的任何组合,并与二进制OR(|)运算符结合在一起。 可用的`flags`值 | Flag | 描述 | | --- | --- | | **`MSG_OOB`** | 处理超出边界的数据 | | **`MSG_PEEK`** | 从接受队列的起始位置接收数据,但不将他们从接受队列中移除。 | | **`MSG_WAITALL`** | 在接收到至少`len`字节的数据之前,造成一个阻塞,并暂停脚本运行(block)。但是, 如果接收到中断信号,或远程服务器断开连接,该函数将返回少于`len`字节的数据。 | | **`MSG_DONTWAIT`** | 如果制定了该flag,函数将不会造成阻塞,即使在全局设置中指定了阻塞设置。 | name 如果套接字的类型为AF_UNIX类型,则name是文件的路径。 否则,对于未连接的套接字,name是远程主机的IP地址,如果套接字是面向连接的,则为NULL。 port 此参数仅适用于AF_INET和AF_INET6套接字,并指定从其接收数据的远程端口。 如果套接字是面向连接的,则端口将为NULL >[danger]如果在UDP套接字上使用socket\_recvfrom并将其与MSG\_DONTWAIT标志结合使用,则如果没有要读取的内容,它将引发PHP警告。 AFAIK,除了用@抑制警告外,没有其他方法可以解决该警告(即,在调用socket\_recvfrom之前无法检查是否有数据) **例子** 本示例将在端口1223的127.0.0.1上启动UDP套接字,并最多打印从远程主机收到的12个字符 ``` 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 "Received $buf from remote address $from and remote port $port" . PHP_EOL; ``` 使用UDP套接字的DNS中继 ``` 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); } ```