Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP如何优雅地关闭本地套接字连接。。。?_Php_Linux_Sockets_Polling_Unix Socket - Fatal编程技术网

PHP如何优雅地关闭本地套接字连接。。。?

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

我有一个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)
我想像我的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()调用的组合来完成这个任务。是的。这并不完美。更好。非常感谢您的帮助,看来我现在可以想出一个答案了。:-)