PHP:发送UDP广播消息,并等待响应

11

我使用这段代码发送UDP广播消息

$ip = "255.255.255.255";
$port = 8888;
$str = "DEVICE_DISCOVERY";

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1); 
socket_sendto($sock, $str, strlen($str), 0, $ip, $port);

socket_recvfrom($sock, $buf, 20, 0, $ip, $port);
echo "Messagge : < $buf > , $ip : $port <br>";

socket_close($sock);

我希望特定的网络设备(在我的情况下,是一些带有以太网盾的Arduino板)响应一个特定的消息。

代码可以运行,但是这样我只能打印出一个响应,而不能打印出所有的响应。


嗯,那你的意思是想要使用循环吗? - Epodax
当然,没问题。但在这种情况下,我不知道如何使用它。 - WhiteLine
你的返回数据是一个数组吗?使用 foreach(){} 循环,找出响应数据的形式,然后使用相应的循环。 - Epodax
响应是一个字符串 - WhiteLine
展示给我们这个字符串。 - Epodax
每个设备都会响应一个字符串,一个非常简单的字符串,比如“abc”。问题不在于响应的类型,而在于如何“监听”所有的响应。 - WhiteLine
1个回答

8
你需要一个while循环,在超时时间内如果没有响应就跳出循环。
首先设置超时时间,例如5秒:
socket_set_option($sock,SOL_SOCKET,SO_RCVTIMEO,array("sec"=>5,"usec"=>0));

还有循环:

while(true) {
  $ret = @socket_recvfrom($sock, $buf, 20, 0, $ip, $port);
  if($ret === false) break;
  echo "Messagge : < $buf > , $ip : $port <br>";
}

完整代码:

$ip = "255.255.255.255";
$port = 8888;
$str = "DEVICE_DISCOVERY";

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); 
socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, 1);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>5, "usec"=>0));
socket_sendto($sock, $str, strlen($str), 0, $ip, $port);

while(true) {
  $ret = @socket_recvfrom($sock, $buf, 20, 0, $ip, $port);
  if($ret === false) break;
  echo "Messagge : < $buf > , $ip : $port <br>";
}

socket_close($sock);

我已经看过这个解决方案了,如果我可以设置这些选项的话,那就太好了:socket_set_option($sock,SOL_SOCKET,SO_BROADCAST,1); - WhiteLine
你可以使用SO_RCVTIMEO,但它不是代替SOL_SOCKET的。 - Marek
如果我这样做:socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>10,"usec"=>0)); 超时会起作用,但广播消息不会;如果我这样做:socket_set_option($sock, SOL_SOCKET, SO_BROADCAST, array("sec"=>10,"usec"=>0)); 什么都不起作用。 - WhiteLine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接