Question

I have a PHP client connecting to a local C server programme via a text-only Unix-domain socket. However, the only way I can get it to shutdown nicely is if I finish the socket session with:

stream_socket_shutdown($sock, 1); // shutdown socket writing
usleep(500 * 1000);           // wait for 0.5 seconds
fclose($sock);                // actually close the socket (finally)

I'd like to shut it down gracefully like my C client:-

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)

However, PHP doesn't appear to have a direct socket poll() equivalent. How can I get PHP to shut down my local socket gracefully?

Était-ce utile?

La solution

Have you tried stream_set_blocking() ? If you set the stream to be non-blocking, you should be able to consume all of the pending data before closing the connection:

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

Edit: used constants, and fixed the set-blocking command to use the correct value.

Explanation: By setting the stream to non-blocking and then reading everything from it, we consume all of the data already in the input buffer. This greatly speeds up the shutdown process by signaling the peer that our buffers are clear and he can send us more messages (like the FIN packets).

It is still possible to get a slow shutdown, but much less likely.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top