Write to socket and process broken pipes

I have PHP code that connects to a socket. I get an intermittent pipe with intermittent writing. It seems that the problems will disappear if you write again into the pipe. I wonder what it takes (the safest way) to recover from it. I am also wondering if socket_write will be able to return without writing the full string that was passed to it. Here is what I have.

function getSocket() { $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 ); if ( $socket === FALSE ) { throw new Exception( "socket_create failed: reason: " . socket_strerror( socket_last_error() )); } } $result = socket_connect($socket, $address); if ($result === false) { throw new Exception("socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket))); } return $socket; } function writeSocket($stmt) { $tries = 0; $socket = getSocket(); do { // Is is possible that socket_write may not write the full $stmt? // Do I need to keep rewriting until it finished? $writeResult = socket_write( $socket, $stmt, strlen( $stmt ) ); if ($writeResult === FALSE) { // Got a broken pipe, What the best way to re-establish and // try to write again, do I need to call socket_shutdown? socket_close($socket); $socket = getSocket(); } $tries++; } while ( $tries < MAX_SOCKET_TRIES && $writeResult === FALSE); } 
+6
source share
3 answers

Q1. I wonder what is required (the safest way) to recover from it.

A: It depends on the application. The socket listener closes the connection, or you specified socket options that you do not show us. How you deal with any of these things depends on the semantics of the application.

Q2. I am also wondering if socket_write will be able to return without writing the full string that was passed to it.

A: Yes. socket_write() cannot write bytes, some bytes, or all bytes before returning. If it returns a value greater than zero but less than the input length, you should adjust the offsets (possibly using substr() ). If it returns zero or less, check socket_last_error() for the possibility of retrying. This circuit is covered in the manual .

+2
source

Have you tried setting SO_KEEPALIVE or SO_SNDTIMEO? You can also check the length of the buffer in your loop to see if all of this has been sent.

Good luck and hth, - Joe

0
source

Use socket_set_nonblock() and fix the while statement:

$writeResult === FALSE must be $writeResult !== FALSE .

0
source

Source: https://habr.com/ru/post/895991/


All Articles