Reputation: 8494
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 fail
Warning: 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.
Upvotes: 1
Views: 2879
Reputation: 165201
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()
and recvfrom()
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.
Upvotes: 4