socket_recvfrom()
(PHP 4 >= 4.1.0, PHP 5, PHP 7)
Receives data from a socket whether or not it is connection-oriented
说明
socket_recvfrom(resource $socket,string &$buf,int $len,int $flags,string &$name[,int &$port]): int
The socket_recvfrom() function receives$lenbytes of data in$buffrom$nameon port$port(if the socket is not of type AF_UNIX)using$socket.socket_recvfrom() can be used to gather data from both connected and unconnected sockets. Additionally, one or more flags can be specified to modify the behaviour of the function.
The$nameand$portmust be passed by reference. If the socket is not connection-oriented,$namewill be set to the internet protocol address of the remote host or the path to the UNIX socket. If the socket is connection-oriented,$nameis NULL. Additionally, the$portwill contain the port of the remote host in the case of an unconnected AF_INET or AF_INET6 socket.
Note:此函数可安全用于二进制对象。
参数
- $socket
The$socketmust be a socket resource previously created by socket_create().
- $buf
The data received will be fetched to the variable specified with$buf.
- $len
Up to$lenbytes will be fetched from remote host.
- $flags
The value of$flagscan be any combination of the following flags, joined with the binary OR(|)operator.
Possible values for$flags Flag Description MSG_OOBProcess out-of-band data. MSG_PEEKReceive data from the beginning of the receive queue without removing it from the queue. MSG_WAITALLBlock until at least$lenare received. However, if a signal is caught or the remote host disconnects, the function may return less data. MSG_DONTWAITWith this flag set, the function returns even if it would normally have blocked. - $name
If the socket is of the type
AF_UNIXtype,$nameis the path to the file. Else, for unconnected sockets,$nameis the IP address of, the remote host, orNULLif the socket is connection-oriented.- $port
This argument only applies to
AF_INETandAF_INET6sockets, and specifies the remote port from which the data is received. If the socket is connection-oriented,$portwill beNULL.
返回值
socket_recvfrom() returns the number of bytes received, or FALSE if there was an error. The actual error code can be retrieved by calling socket_last_error(). This error code may be passed to socket_strerror() to get a textual explanation of the error.
范例
socket_recvfrom() example
<?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 "Received $buf from remote address $from and remote port $port" . PHP_EOL; ?>
This example will initiate a UDP socket on port 1223 of 127.0.0.1 and print at most 12 characters received from a remote host.
参见
socket_recv()从已连接的socket接收数据socket_send()Sends data to a connected socketsocket_sendto()Sends a message to a socket, whether it is connected or notsocket_create()创建一个套接字(通讯节点)
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).
Pay attention! On some PHP version the MSG_DONTWAIT flag is not defined (see https://bugs.php.net/bug.php?id=48326)
MSG_DONTWAIT doesn't seem to exist in windows sockets. However socket_set_nonblock() seems to do the trick.
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.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);
}
?>
