PHP套接字阻塞

时间:2012-07-04 10:43:27

标签: php sockets tcp

基本上,我正在使用阻止 TCP套接字以及socket_accept()。我遇到的问题是,由于显而易见的原因,因为I / O阻塞,因此在PHP能够操作的任何时候只能有一个连接到套接字。我很好,因为这是我追求的行为。

但是,如果客户端打开与我的PHP服务器的连接,如果他们只是打开套接字并且不发送任何数据,则套接字和守护程序将变得无用,因为阻塞I / O将不允许新请求

有没有办法检测一个只是不发送数据的客户端(如无传输超时)或类似的东西?我宁愿不使用非阻塞I / O.

2 个答案:

答案 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服务器做一次伪线程...

这是一个要点:https://gist.github.com/eda7d47ec4e475af531e