如何检查套接字是否存活

时间:2014-06-06 18:51:13

标签: php sockets

我有一个小服务器(用PHP编写),监听使用socket_create创建的套接字并使用socket_accept接受连接。使用socket_select扫描所有连接,并且每当该调用返回时,服务器接受来自套接字的新连接读取。当客户端断开连接时,socket_select返回与之关联的套接字,然后服务器可以通过检查socket_read返回空字符串来检测断开连接。

到目前为止,所有这些都是"通过这本书"并且运行良好,但问题是如果客户端断开连接(例如,如果它崩溃),那么它的套接字进入socket_select返回的列表(如预期的那样),但是当服务器调用{ {1}},它会触发错误:

socket_read

显然,在调用socket_read(): unable to read from socket之前,我必须在套接字上添加一些检查,但我无法找到它会是什么。检查该套接字的方法是什么?请参阅代码中的注释。

socket_read

1 个答案:

答案 0 :(得分:0)

您没有检查select的结果,必须这样做才能知道是否有可供阅读的套接字。

$r = socket_select($readable_sockets, $null, $null,  0);
if ($r === false) {
    /* socket_select  Error handling */
} else if ($r > 0) {
    /* At least at one of the sockets something interesting happened */
}

select函数将更改$readable_sockets数组以防有待读取的内容,或者在超时的情况下可能未定义或未触及。

注意:请注意,需要非常小心地处理某些套接字实现。

一些基本规则:

  • 您应该始终尝试使用socket_select()而不会超时。您
    如果没有可用数据,程序应该无所事事。码 取决于超时的通常不是便携式的,也很难 调试。

  • 如果不是,则不得将任何套接字资源添加到任何集合中 打算在socket_select()电话后检查其结果,并且 适当回应。在socket_select()返回后,所有套接字
    必须检查所有数组中的资源。任何套接字资源 必须写入可写的,以及任何套接字资源
    必须阅读

  • 如果您读取/写入套接字,请注意数组中的返回值 他们不一定要读/写全部数据 您已请求。准备好甚至只能读/写 一个字节。

  • 大多数套接字实现都是常见的 使用except数组捕获的异常是超出范围的数据 收到了插座。

根据我的经验select没有办法知道套接字何时崩溃,直到你尝试从中读取它时,永远不会将崩溃的套接字作为候选进行读取,除非在正常关闭或关闭时完成另一端。你可以做的一件事是每个套接字都有一个超时,如果套接字没有活动,比方说30分钟,那么你可以丢弃它。

我还将用户的套接字与主套接字分开。对用户的套接字执行选择并分派其数据,然后对主套接字执行选择并接受新连接。但这取决于你,如果你想在每次迭代中检查主套接字,那就没关系。