php udp работает только на loopback - PullRequest
1 голос
/ 08 февраля 2011

Я пытаюсь написать клиент 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);

Если я назову его с? Циклов = 10 & ip = [внешний ip], он не будет работать, он продолжит печатать:

Предупреждение : socket_sendto () [function.socket-sendto]: невозможно записать в сокет [22]: Неверный аргумент в / вар / WWW / по умолчанию / Тесты / UdpTest.php на линии 37
sendto ошибка

Предупреждение : socket_recvfrom () [function.socket-recvfrom]: невозможно получить из [11]: Ресурс временно недоступен в / вар / WWW / по умолчанию / Тесты / UdpTest.php на линии 38
62.180.108.236:11116 -

Если я использую ?cylces=10&ip=127.0.0.1, он работает как положено, получая то, что отправил. То же самое, если я использую два разных порта и пытаюсь запустить netcat на этой машине. Внешний ip является физическим адресом этой машины, и скрипт вызывается из apache, кстати.

1 Ответ

3 голосов
/ 10 февраля 2011

Проблема в интерфейсе, к которому вы привязаны.

Привязка к шлейфу (127.0.0.1) означает, что вы можете общаться только с устройствами в этом сетевом интерфейсе.А поскольку локальный компьютер является единственным устройством на этом интерфейсе, sendto() и recvfrom() не будут работать при задании адреса в другой сети.

Чтобы решить проблему, выполните привязку ко всем интерфейсам (0.0.0.0) или на определенный внешний IP-адрес с сервера.Это позволит вам общаться с любым устройством в сети, к которому подключен IP-адрес.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...