2011-02-08 5 views
1

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); 

= 10 & IP = [외부 IP가]가 작동하지 않습니다, 그것은 유지 인쇄 :

경고 : socket_sendto() [function.socket -sendto] : 수없는 는 소켓에 쓸 [22] : 라인 /var/www/default/Tests/UdpTest.php 에서 잘못된 인수 37
sendto를 실패

경고 : socket_recvfrom()는 function.socket-에 recvfrom]에 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

'socket_bind'를 루프백에서 서버의 외부 IP 주소로 변경해보십시오. – ircmaxell

+0

대단히 감사합니다. 0.0.0.0에 대한 바인딩도 작동했습니다. :) – Caesar

답변

3

문제는 바인딩하려는 인터페이스입니다.

루프백 (127.0.0.1)으로 바인딩한다는 것은 해당 네트워크 인터페이스의 장치와 만 통신 할 수 있음을 의미합니다. 로컬 컴퓨터가 해당 인터페이스의 유일한 장치이기 때문에 다른 네트워크에서 주소를 지정하면 sendto()recvfrom()이 실패합니다.

문제를 해결하려면 모든 인터페이스 (0.0.0.0) 또는 서버의 특정 외부 IP 주소에 바인딩하십시오. 그러면 IP가 연결된 네트워크의 모든 컴퓨터와 통신 할 수 있습니다.

관련 문제