php 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&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 调用的,顺便说一句。
I am trying to write a php udp client.
//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);
If I call it with ?cycles=10&ip=[external ip] it won't work, it keeps printing:
Warning: socket_sendto() [function.socket-sendto]:
unable to write to socket [22]:
Invalid argument in
/var/www/default/Tests/UdpTest.php
on line 37
sendto
failWarning:
socket_recvfrom() [function.socket-recvfrom]:
unable to recvfrom [11]: Resource
temporarily unavailable in
/var/www/default/Tests/UdpTest.php
on line 38
62.180.108.236:11116 -
If I use ?cylces=10&ip=127.0.0.1
it works as expected, receiving what it has sent. It's the same if I use two different ports and try running netcat on that machine. The external ip is a physical adress of that machine and the script is called from apache, btw.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于您所绑定的接口。
绑定到环回 (
127.0.0.1
) 意味着您只能与该网络接口上的设备进行通信。由于本地计算机是该接口上的唯一设备,因此当给定另一个网络上的地址时,sendto()
和recvfrom()
将失败。要解决此问题,请绑定到所有接口 (
0.0.0.0
) 或绑定到服务器中的特定外部 IP 地址。这将允许您与 IP 连接到的网络上的任何计算机进行通信。The problem is the interface that you're binding to.
Binding to loop-back (
127.0.0.1
) means that you can only communicate with devices on that network interface. And since the local machine is the only device on that interface,sendto()
andrecvfrom()
will fail when given an address on another network.To solve the problem, either bind to all interfaces (
0.0.0.0
) or to a specific external IP address from the server. That will allow you to communicate with any machine on the network that IP is connected to.