我最近一直在使用PHP构建TCP服务器(我知道一开始的选择是错误的,但这是工作标准),所以我已经到了有一个可靠的原型可以对它进行测试的地步,它显示出了良好的结果。一开始,我使用socket函数来处理服务器的连接,它运行得很好,但项目的主要任务之一是确保通道的安全,所以我切换到stream_socket。
我想要的是stream_socket组中的socket_last_error等效项,这样我就可以知道与客户端的连接何时关闭。在当前情况下,所有进程都将等待超时计时器释放,即使客户端已经关闭。
我在网上搜索了一下,发现没有办法通过PHP来解决这个问题,我发现有些人打开了关于它的问题单,要求流的socket_last_error等价物。https://bugs.php.net/bug.php?id=34380
那么无论何时FIN_WAIT信号被升高或不被升高,都有什么要知道的吗?
谢谢你,
我认为stream_socket
家族不可能,看起来级别太高了。
我试着做了一个非常棘手的解决方案,我不知道它是否适用于你,它不太可靠:
<?php
set_error_handler('my_error_handler');
function my_error_handler($no,$str,$file,$line) {
throw new ErrorException($str,$no,0,$file,$line);
}
$socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
if (!$socket) {
echo "$errstr ($errno)n";
} else {
while ($conn = stream_socket_accept($socket)) {
foreach (str_split('The local time is ' . date('n/j/Y g:i a') . "n") as $char) {
echo $char;
try {
fwrite($conn,$char);
} catch (ErrorException $e) {
if (preg_match("/^fwrite(): send of 1 bytes failed with errno=([0-9]+) ([A-Za-z /]+)$/",$e->getMessage(), $matches)) {
list($errno,$errstr) = array((int) $matches[1], $matches[2]);
if ($errno === 32) {
echo "n[ERROR] $errstr"; // Broken pipe
}
}
echo "n[ERROR] Couldn't write more on $conn";
break;
}
fflush($conn);
}
fclose($conn);
}
fclose($socket);
}
echo "n";
?>
启动:php ./server.php
连接:nc localhost 8000 | head -c1
服务器输出:
The loca
[ERROR] Broken pipe
[ERROR] Couldn't write more on Resource id #6