2012-03-16 12 views
1

PHPでコーディングされたWeb IMクライアントのバックエンド用のIPCシステムに取り組んでいます。私はUnixソケットを実装しようとしていますが、作成したソケットファイルを再利用するのに問題があります。ここではイベントのためにソケットをリッスンするコードです。PHP Unixソケットファイルの再利用

<?php 

$socket_file = "../tmp/sockets/test.sock"; 

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0); 

socket_bind($socket, $socket_file); 
socket_listen($socket); 

socket_select($temp = array($socket), $temp = null, $temp = null, 20); 

$client = socket_accept($socket); 
socket_set_nonblock($client); 
$buffer = socket_read($client, 2048); 

echo $buffer; 

socket_close($client); 
socket_close($socket); 

このスクリプトを初めて実行すると、ソケットファイルtest.sockが作成され、接続を待機します。送信スクリプトを実行するとき:

<?php 

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0); 

socket_connect($socket, "../tmp/sockets/test.sock"); 

$msg = "\nThis is a test\r\n"; 

socket_write($socket, $msg, strlen($msg)); 

socket_close($socket); 

もう1つのスクリプトは、受信したメッセージを出力して終了します。だから、この点までのすべてが私が期待するように働いています。私は

rm ~/tmp/sockets/test.sock 

が、それはソケットファイルを再作成し、正常に動作聞くスクリプトを再実行し実行した場合

Warning: socket_bind() [function.socket-bind]: unable to bind address [98]: Address already in use 

:私はそれがこのエラーをスローリスニングスクリプトを再実行しようとすると問題があります。だから私の質問です:リッスンスクリプトは、既存のソケットファイルに再接続し、別のスクリプトが接続されていなくてもソケットファイルをリッスンしている場合でも、送信スクリプトがソケットに書き込むことができますか?私はUNIXソケットのコンセプトに慣れていないので、どんな助けでも大歓迎です!

答えて

1

socket_close()はファイルを削除しないので、手動で行う必要があります(unlink()) 2番目の質問については、接続できるかもしれませんが、送信するものはすべて破棄されます。やってみなよ。

5

unix(7)マニュアルページをご覧ください。終わりに向かって、それは言う:

Binding to a socket with a filename creates a socket in the file system that must be deleted by the caller when it is no longer needed (using `unlink(2)`). The usual UNIX close-behind semantics apply; the socket can be unlinked at any time and will be finally removed from the file system when the last reference to it is closed.

だから右のサーバーでsocket_bind()後にソケットファイルを削除します。

+0

これはスクリプトがそれを聞いて行われた後、ソケットファイルを削除する必要があります...そして、それは別のスクリプトは、そのソケットファイルを開いて、何も私の目標だったことに耳を傾けていない場合は、それに書き込むことができませんでした意味を意味します。私は、これらのソケットが動作しないように見えるので、代わりにFIFO特殊ファイル(名前付きパイプ)を使用する方法を検討しています。 –

+0

一度聞いてみると、受け入れとクライアントの処理をループに入れて、複数のクライアントを扱うことができますか? –

+0

@NikolaiNFetissov、 'socket_bind'の直後にリンクを解除しようとしましたが、ファイルがすぐに削除されました。クライアントは接続できませんでした。どうしましたか? – seelts