2009-04-07 4 views
2

을 듣고 내 코드입니다 :PHP : 소켓은 여기에 문제

내가 다른 응용 프로그램으로 "테스트"를 보내
<?php 

$host = "127.0.0.1"; 
$portListen = 1234; 
$portSend = 1240; 


// create socket 
$sSender = socket_create(AF_INET, SOCK_STREAM, 0); 

socket_connect($sSender, $host, $portListen); 

socket_write($sSender, "test", strlen ("test")); 


$sListen = socket_create(AF_INET, SOCK_STREAM, 0); 
socket_set_option($sListen, SOL_SOCKET, SO_REUSEADDR, 1); 

socket_bind($sListen, $host, $portSend); 

socket_listen($sListen,1); 
$dataSock = socket_accept($sListen); 
echo socket_read($dataSock, 3, PHP_NORMAL_READ); 

// close sockets 
socket_close($sSender); 
socket_close($sListen); 
?> 

, 그것은 수신, 그리고 "ACK"다시 보냅니다. 문제는 단지 한 번만 할 수 있다는 것입니다. 새로 고침하면 주소가 이미 사용되는 오류가 발생합니다. 나는 php.net에 제안 된 솔루션을 시도했지만 아무 소용이 없습니다. socket_close() 전에 socket_shutdown()을 시도하면 연결된 경고가 표시되지 않고 새로 고침을하면 절대 종료되지 않습니다.

소켓이 즉시 닫히지 않는 이유는 데이터가 버퍼에 남아 있기 때문입니다. 그러나 당신이 볼 수 있듯이 나는 오직 단 하나의 연결을 듣기 위해 명시 적으로 말합니다. 게다가 나는이 스크립트에서 내 응용 프로그램과 3을 읽는 중 3 개의 문자 만 보내고 있습니다.

내가 뭘 잘못하고 있니?

편집 : 2 소켓을 사용하는 이유는 소켓을 이미 연결 한 상태에서 write()를 수신 할 수 없기 때문입니다. write()가 잘못된 인수 오류를 내면 listen()을 건너 뛰고 read()를 위해 곧바로 진행합니다.

+0

이 작업을 수행하는 훨씬 쉬운 방법이 있습니다. 이 블로그 게시물을 확인하십시오. http://www.christophh.net/2012/07/24/php-socket-programming/ –

답변

2

몇 시간 동안 잠을 자고 코드와 문서를 다시 분석 한 후에 모든 것을 고칠 수있었습니다. 너희들 말이 맞아, 1 소켓은 참으로 충분하고 올바른 방법이다.

<?php 

$host = "127.0.0.1"; 
$portListen = 1234; 
$sSender = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); 

socket_connect($sSender, $host, $portListen) or die("Could not connect\n"); 

socket_write($sSender, "test", strlen ("test")) or die("Could not write output\n"); 

echo socket_read($sSender, 3, PHP_NORMAL_READ); 

socket_close($sSender); 
?> 

매우 간단하다!

1

왜 읽고 쓰는 데 2 ​​개의 소켓을 만들어야합니까? 이상한 디자인처럼 보입니다. 클라이언트 응용 프로그램은 일반적으로 서버에 대한 소켓 연결을 연 다음 요청을 보내고 동일한 소켓에서 서버의 응답을 읽습니다. 또한 리스닝 소켓 (iow 서버)을 만들면 방화벽이나 NAT 게이트웨이가 확장되지 않습니다.

yor 덧글에 대한 답변 : 수신 할 필요가 없습니다. (서버가 아직 응답하지 않은 경우 작업을 차단할 수도 있음).

+0

정확한 디자인이라고 생각했습니다. 소켓 socket_listen() [function.socket-listen] : 소켓 [0]에서 수신 할 수 없습니다. 이미 연결된 소켓에서 연결 요청이 이루어졌습니다. C : \ Wamp \ www \ sock.php 22 번 줄에 있습니다. – syaz

1

연결이 닫힌 후 소켓이 지연 상태가되어 (닫는 동안) 패킷이 손실되었다가 다시 전송되면 응답은 RST (재설정)이 아닌 깨끗한 승인이됩니다. 이것은 TCP 사양의 일부이며, 멈추게 할 수 없습니다.

Listen(1)은 하나의 연결 만 수락한다는 의미는 아니며 응용 프로그램을 기다리는 최대 연결 1 개를 accept()으로 유지하는 것을 의미합니다. 그래서 당신이 처음을 받아들이 자마자 소켓은 더 많은 것을들을 준비가되었습니다.

다른 사람들처럼, 나는 이상한 디자인이 왜 궁금하지만, 그게 당신의 문제를 제시하고 반드시 귀하의 실제 계획을 제시하지 않는 끓인 예제라고 가정합니다.