0

基本的に、ブロッキングTCP ソケットとsocket_accept(). 私が抱えている問題は、明らかな理由により、I/O がブロックされているため、PHP が操作できるソケットへの接続は一度に 1 つしかないことです。これは私が求めている動作であるため、これで問題ありません。

ただし、クライアントが PHP サーバーへの接続を開く場合、ソケットを開いたままにしてデータを送信しないだけの場合、ブロッキング I/O が新しい要求を許可しないため、ソケットとデーモンは役に立たなくなります。

単純にデータを送信していないクライアント (無送信タイムアウトなど) を検出する方法はありますか? ノンブロッキング I/O は使用したくありません。

4

2 に答える 2

1

と同等の機能を 呼び出すだけstream_set_timeoutで、特定のタイムアウト後にブロッキングの読み取りと書き込みを終了させることができます。

$s = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!socket_bind($s, '127.0.0.1', 0)) die("bind failed");
if (!socket_listen($s)) die("listen failed");
socket_getsockname($s, $localA, $localPort);
echo 'Listening on ' . $localA . ': ' . $localPort . "\n";

$c = socket_accept($s);

// Warning: Ugly hack ahead.
// This just mitigates the problem somewhat, and doesn't actually solve it
socket_set_option($c, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>2,'usec'=>0));
socket_set_option($c, SOL_SOCKET, SO_SNDTIMEO, array('sec'=>2,'usec'=>0));

$r = socket_read($c, 1024);
echo 'read finished: got ' . var_export($r, true) . "\n";

これはハックであることに注意してください。悪意のある攻撃者は、1秒あたり1バイト程度しか送信できません。

これらのクレイジーなハックに時間を費やす代わりに、実際には非ブロッキングIOに切り替えるか、受け入れられたソケットを別のスレッド/プロセスで処理する必要があります。

于 2012-07-04T10:48:49.887 に答える
0

Tudor Barbu Thread クラスを使用して、Websocket サーバーの疑似スレッドを一度実行しました...

ここに要点があります:https://gist.github.com/eda7d47ec4e475af531e

于 2012-07-04T11:24:17.763 に答える