基本上,我正在使用阻止 TCP套接字以及socket_accept()
。我遇到的问题是,由于显而易见的原因,因为I / O阻塞,因此在PHP能够操作的任何时候只能有一个连接到套接字。我很好,因为这是我追求的行为。
但是,如果客户端打开与我的PHP服务器的连接,如果他们只是打开套接字并且不发送任何数据,则套接字和守护程序将变得无用,因为阻塞I / O将不允许新请求
有没有办法检测一个只是不发送数据的客户端(如无传输超时)或类似的东西?我宁愿不使用非阻塞I / O.
答案 0 :(得分:1)
您可以简单地调用the equivalent of 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个字节左右。
不要在这些疯狂的黑客中投入时间,而应该切换到非阻塞IO或在单独的线程/进程中处理接受的套接字。
答案 1 :(得分:0)
我使用Tudor Barbu Thread类为Websocket服务器做一次伪线程...