PHP如何优雅地关闭本地套接字连接。。。?
我有一个PHP客户端,通过一个纯文本Unix域套接字连接到本地C服务器程序。但是,使其正常关闭的唯一方法是使用以下命令完成套接字会话:PHP如何优雅地关闭本地套接字连接。。。?,php,linux,sockets,polling,unix-socket,Php,Linux,Sockets,Polling,Unix Socket,我有一个PHP客户端,通过一个纯文本Unix域套接字连接到本地C服务器程序。但是,使其正常关闭的唯一方法是使用以下命令完成套接字会话: stream_socket_shutdown($sock, 1); // shutdown socket writing usleep(500 * 1000); // wait for 0.5 seconds fclose($sock); // actually close the socket (finally
stream_socket_shutdown($sock, 1); // shutdown socket writing
usleep(500 * 1000); // wait for 0.5 seconds
fclose($sock); // actually close the socket (finally)
我想像我的C客户机一样优雅地关闭它:-
shutdown(connection_fd, SHUT_WR); // tell server we've stopped sending queries
// Read from the socket until poll(connection_fd) yields POLLRDHUP / POLLHUP / POLLERR / POLLNVAL
shutdown(connection_fd, SHUT_RDWR); // tell connection we've stopped listening
close(connection_fd); // close the whole connection (finally)
但是,PHP似乎没有与之等效的直接套接字poll()。如何让PHP优雅地关闭本地套接字?您是否尝试过?如果将流设置为非阻塞,则应该能够在关闭连接之前使用所有挂起的数据:
socket_shutdown($sock, STREAM_SHUT_WR);
stream_set_blocking($sock, 0);
while( fgets($sock) !== false ) { ; }
fclose($sock);
编辑:使用了常量,并修复了set blocking命令以使用正确的值
解释:通过将流设置为非阻塞,然后从中读取所有内容,我们将消耗输入缓冲区中已经存在的所有数据。这通过向对等方发送信号,告知我们的缓冲区已清除,他可以向我们发送更多消息(如FIN数据包),从而大大加快了关机过程
缓慢关机仍然是可能的,但可能性要小得多。Aha-你说得对99%。如果将第一行更改为“socket_shutdown($sock,0);”(这就是你的意思:-)那么它确实似乎优雅地关闭了单一连接。但是,我不确定当多个连接处于活动状态时,这是否会像预期的那样工作——我真的不希望我的PHP处于活动状态。所以也许这不是完整的答案。。。您同意吗?它实际上不会旋转等待,因为套接字处于非阻塞模式。取而代之的是,所有待处理的数据都将被读取,而无需等待另一端发送更多数据,这几乎在所有情况下都会加快关机操作。我完全同意,所有已发送的数据都将到达。但是,如果为了响应,服务器必须从(例如)连接的I2C设备获取一些数据,那么在发送查询的客户端和响应的服务器之间可能会有很大的延迟。我猜在那些(频繁的)情况下,PHP会旋转等待,如果可能的话,我宁愿避免这种情况。我猜我最终会构建一个非阻塞fgets()调用和usleep()调用的组合来完成这个任务。是的。这并不完美。更好。非常感谢您的帮助,看来我现在可以想出一个答案了。:-)