PHP如何正常关闭本地套接字连接......?

时间:2012-11-08 18:06:58

标签: 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)

我想像我的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正常关闭本地套接字?

1 个答案:

答案 0 :(得分:4)

您是否尝试过 stream_set_blocking() ?如果将流设置为非阻塞,则应该能够在关闭连接之前使用所有挂起的数据:

socket_shutdown($sock, STREAM_SHUT_WR); 
stream_set_blocking($sock, 0);
while( fgets($sock) !== false ) { ; }
fclose($sock);

编辑:使用了常量,并修复了set-blocking命令以使用正确的值。

说明:通过将流设置为非阻塞,然后从中读取所有内容,我们将使用输入缓冲区中已有的所有数据。这通过向对等方发信号通知我们的缓冲区是清除的并且他可以向我们发送更多消息(如FIN包)来大大加快关闭过程。

仍有可能实现缓慢关闭,但不太可能。