I came up with these two functions, fully-replaceable and reliable alternatives of fread()/fwrite() in a socket context:
function fullread ($sd, $len) {
$ret = '';
$read = 0;
while ($read < $len && ($buf = fread($sd, $len - $read))) {
$read += strlen($buf);
$ret .= $buf;
}
return $ret;
}
function fullwrite ($sd, $buf) {
$total = 0;
$len = strlen($buf);
while ($total < $len && ($written = fwrite($sd, $buf))) {
$total += $written;
$buf = substr($buf, $written);
}
return $total;
}The functions are "greedy", i.e. trying to read/write as much data as possible at once. If the inside call to fread()/fwrite() reads/writes less than expected, then the next iteration eats up the remainder. Very smart as only the largest possible chunks are read/written. Only in case of a broken pipe (dropped connection during execution) the functions return less than the specified length. Otherwise it is guaranteed that upon termination
strlen(fullread($sd, $len)) == $lenand
fullwrite($sd, $buf) == strlen($buf)Works perfectly with a socket descriptor returned from stream_socket_client(), and I hope it will do so with fsockopen() as well.
Yay! Caused me two weeks of fuss how unreliable are fread()/fwrite() to suddenly come up with this simple, smart and elegant solution.
0 comments:
Post a Comment