|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2003-01-07 06:00 UTC] bjarne at sourcetech dot se
The following code doesn't work with php4.3.0
As foef() never returns true it got stuck in the while()-loop...
When running the same code in php4.2.3 it works as it should so it seems like a 4.3.0 issue...
( feof() returns true in 4.2.3... )
The scenario consists of the script connecting to a host which immediatly replies with a textstring; "OK", which in turn is printed out...
/Regards
Bjarne
// Open a socket and connects to the host
$fp = fsockopen ($myhost, $myport, $errno, $errstr, 30);
// check for valid filepointer
if (!$fp)
{
echo "$errstr ($errno)<br>\n";
}
else
{
// sets the socket to non-blocking
socket_set_blocking($fp,FALSE);
// read data from socket upto EOF in 128 byte chunks
while (!feof($fp)) // <= FAILS IN PHP 4.3.0!!!!!
{
$buffer .= fgets ($fp,128);
}
// closing socket
fclose ($fp);
// printing the buffer
print "Buffer:" . $buffer;
}
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 19 09:00:01 2025 UTC |
It seems that socket_set_blocking($fp,FALSE); results in other peculiar behaviour. When connecting to SMTP server, the server sends some data across the socket right away, usually something identifying the server. $fp = fsockopen("mail_server", 25); var_dump(fgets($fp, 1024)); fclose($fp); returns the server identify string $fp = fsockopen("mail_server", 25); socket_set_blocking($fp,FALSE); var_dump(fgets($fp, 1024)); fclose($fp); returns (false) $fp = fsockopen("mail_server", 25); sleep(1); socket_set_blocking($fp,FALSE); var_dump(fgets($fp, 1024)); fclose($fp); returns identify string. The position of the sleep() call can be after socket_set_blocking() as well.The following works for me: $fp = fsockopen("localhost", 25); stream_set_blocking($fp, false); fwrite($fp, "QUIT\r\n"); while(!feof($fp)) { $data = fgets($fp); var_dump($data); } echo "\nAll done\n"; Remember that feof() will only return true when there is no more data in the internal buffer held by the stream, so you need to drain off any input by consuming it all first.The following works for me: $fp = fsockopen("localhost", 25); stream_set_blocking($fp, false); fwrite($fp, "QUIT\r\n"); while(!feof($fp)) { $data = fgets($fp); var_dump($data); } echo "\nAll done\n"; Under Win2000, WinXP, Linux2.4.19 (with IPv6), FreeBSD4.5 (with IPv6)... Not verified at all for me.This is expected behaviour. feof() will only return true for a socket stream when the connection has been closed. If you are running in non-blocking mode, you need to check the return value of fgets to see if it is false. If it returns false it simply means that there is no more data at that time. You can then check if the EOF has been reached. Your script is responsible for implementing some kind of timeout to catch the kind of communication error you have described (both sides of the socket are waiting for the other to send data). This is difficult to do with a raw non-blocking socket, so instead of doing that, there are two other techniques which are more flexible (for most users): 1. Use stream_set_timeout() on a regular blocking socket. Useful only if you are using a single socket to read from. 2. Use stream_select() on a number of regular blocking sockets. Useful if your script is talking to a number of servers concurrently. Both of these allow you to set a timeout duration; the first will cause your fgets() and fread() calls to timeout after the specified duration; they will return false in that case, which you should check for and break out of your while loop. while (!feof($fp)) { $data = fgets($fp); if ($data === false) break; } stream_select() will wait for up to the timeout duration for data to arrive on any of the streams that you pass as parameters. You can then read data from the relevant streams. This is slightly more complicated to implement than using stream_set_timeout, but more powerful overall. feof() is definitely working the way it should, as are the other functions that I have mentioned. I'm changing this to a documentation problem, because we should explain about non-blocking sockets and some of the common pitfalls more clearly in the docs.