php udp仅适用于环回

时间:2011-02-08 14:28:44

标签: php sockets udp

我正在尝试编写一个php udp客户端。

//Parsing values
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors","1");

$cycles = $_GET['cycles'];
$cycles = $cycles > 600 ? 600 : $cycles;
if(!isset($_GET['lport']) || $_GET['lport'] < 1500 || $_GET['lport'] > 65534) {
    $rport = 11115;
} else {
    $rport = $_GET['lport'];
}
if(!isset($_GET['sport']) || $_GET['sport'] < 1500 || $_GET['sport'] > 65534) {
    $port = 11115;
} else {
    $port = $_GET['sport'];
}
$from = isset($_GET['ip']) ? $_GET['ip'] : '127.0.0.1';

//Relevant code starts here 
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($socket, '127.0.0.1', $rport);
socket_set_nonblock($socket);

while($cycles--) {
    $msg = "PING! " . $cycles;
    echo socket_sendto($socket, $msg, strlen($msg), 0, $from, $port) ? "sendto success<br>" : "sendto fail<br>";
    socket_recvfrom($socket, $buf, 1000, 0, $from, $port); //0x40 is MSG_DONTWAIT 
    echo "$from:$port - $buf<br>" . PHP_EOL;
    sleep(1);
}

socket_close($socket);

如果我用它来调用?cycles = 10&amp; ip = [external ip]它将无效,它会继续打印:

  

警告:socket_sendto()[function.socket-sendto]:   无法写入套接字[22]:   中的参数无效    /var/www/default/Tests/UdpTest.php 的   在线 37
发送到   失败

警告:   socket_recvfrom()[function.socket-recvfrom]:   无法回收[11]:资源   暂时无法进入    /var/www/default/Tests/UdpTest.php 的   在线 38
  62.180.108.236:11116 -

如果我使用?cylces=10&ip=127.0.0.1,它会按预期工作,接收已发送的内容。如果我使用两个不同的端口并尝试在该计算机上运行netcat,它也是一样的。外部ip是该机器的物理地址,脚本从apache,btw。

调用

1 个答案:

答案 0 :(得分:3)

问题是您绑定的界面。

绑定到环回(127.0.0.1)意味着您只能与该网络接口上的设备通信。由于本地计算机是该接口上唯一的设备,因此在另一个网络上给出地址时,sendto()recvfrom()将失败。

要解决此问题,请绑定到所有接口(0.0.0.0)或绑定到服务器的特定外部IP地址。这将允许您与IP连接到的网络上的任何计算机进行通信。