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 — Bağlantılı olsun olmasın bir soketten veri alır
Açıklama
$soket
, string &$tmmpon
, int $uzunluk
, int $seçenekler
, string &$isim
[, int &$port
] )
socket_recvfrom() işlevi belirtilen
soket üzerinden tampon
tamponundan uzunluk baytlık veriyi
port. porttaki isim'den alır.
İşlev bağlantılı (tcp) ve bağlantısız (udp) soketlerle çalışabilir. Ayrıca,
bazı seçeneklerle işlevin davranışında değişiklik yapılabilir.
isim ve port gönderimli
aktarılmalıdır. Soket bağlantı yönelimli değilse isim
değiştirgesine uzak konağın IP adresi veya Unix soketinin dosya yolu
atanacaktır. Soketin bağlantı yönelimli olması durumunda
isim NULL'dur. Bunun yanında, soketin bir
bağlantısız AF_INET veya AF_INET6
soket olması durumunda port uzak konağın port
numarasını içerecektir.
Değiştirgeler
-
soket -
socket_create() ile oluşturulmuş geçerli bir soket özkaynağı.
-
tampon -
Alınan verinin yerleştirileceği tampon.
-
uzunluk -
Uzak konaktan alınacak azami bayt sayısı.
-
seçenekler -
Aşağıdaki değerlerin bitsel VEYAlanmış (|) bir birleşimi olabilir
Olası seçeneklerSeçenek Açıklama MSG_OOBBand dışı veri işlenir. MSG_PEEKVeri alım kuyruğunun başlangıcından alınırken kuyruktan silinmez. MSG_WAITALLuzunlukbayt alınıncaya kadar soket baskılanır. Ancak, bir sinyal alınırsa veya uzak konak bağlantıyı keserse işlev daha az veriyle dönebilir.MSG_DONTWAITİşlev bekleme kipinde olsa bile bu seçenek işlevin beklemeden dönmesine sebep olur. -
isim -
Soket
AF_UNIXtüründeyse dosya yolu, bağlantısız soketse uzak konağın IP adresi, bağlantı yönelimli bir soketseNULL'dur. -
port -
Sadece
AF_INETveAF_INET6soketlere uygulanır ve verinin alındığı uzak portu belirtir. Soket bağlantı yönelimli iseportNULLolacaktır.
Dönen Değerler
socket_recvfrom() işlevi alınan bayt sayısını döndürür.
Bir hata oluşmuşsa FALSE döner. Hata kodu
socket_last_error() işlevi ile alınabilir. Bu hata
kodunu socket_strerror() işlevine aktararak hatayı
açıklayan dizgeyi alabilirsiniz.
Örnekler
Örnek 1 - socket_recvfrom() örneği
<?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 "$from adresinin $port. portundan $buf bayt alındı" . PHP_EOL;
?>
Bu örnek 127.0.0.1 adresindeki 1223. port üzerinde bir UDP portu oluşturup uzak konaktan alınacak 12 bayta kadar veriyi gösterir.
Sürüm Bilgisi
| Sürüm: | Açıklama |
|---|---|
| 4.3.0 | socket_recvfrom() artık ikil olarak güvenli. |
Ayrıca Bakınız
- socket_recv() - Bağlı bir soketten veri alır
- socket_send() - Bağlı bir sokete veri gönderir
- socket_sendto() - Bağlı olsun olmasın bir sokete ileti gönderir
- socket_create() - Bir soket oluşturur (iletişim için bir uç)
I said in my previous note that I'd add a secondary post when I found out more about how to use socket_recvfrom(). So here it is.
As I suspected, the example given is dead-flat-wrong and should be avoided. You WILL need to use pointers like the description at the top of the page says. My working socket_recvfrom() command looks like this:
$bytes = socket_recvfrom ($socket, &$udp_reply, 100, 0, &$from_addr, &$from_port);
Also, even if you have no interest in the the information at all, you must create the $from_addr and $from_port variables and pass them by reference. PHP doesn't support passing in NULL just because you might not give a rat's patootie about the information.... ;)
R.
The example doesn't match the format described at the top of the page. It appears to me that to use this command to receive UDP data, I need to format my calling parameter as follows:
int socket_recvfrom
(
resource $socket, // Created this with socket_create
string &$buf, // This is a pointer!!
int $len, // I know the amount of data
int $flags, // I know the flags I want
string &$name, // This is ALSO a pointer!
int &$port // This is ALSO a pointer, TOO!!
);
The example doesn't use any pointers, just values, and I didn't think socket_bind was necessary for UDP sockets. At least, it isn't in C. Anybody got a example that does work?? (Because this doesn't see to so far.)
If I do stumble on a combination of settings that works, I'll post it -- but this doesn't seem to be the most active page on PHP.net....
R.
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);
}
?>
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
