ID:               21485
 Updated by:       [EMAIL PROTECTED]
-Summary:          feof() doesn't returns true on a socket stream
 Reported By:      [EMAIL PROTECTED]
 Status:           Open
-Bug Type:         Sockets related
+Bug Type:         Documentation problem
 Operating System: Win2K/Linux
 PHP Version:      4.3.0
 Assigned To:      wez
 New Comment:

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.



Previous Comments:
------------------------------------------------------------------------

[2003-01-27 03:42:47] [EMAIL PROTECTED]

Sorry for my late respons, i didnt know u were waiting for input...

I think the reason your example works is because the smtp-server closes
the socket after the "QUIT" -command.

Try to "misspell" it and see what happens...(i.e 'QUIIT')
You get a "unrecognized command" response from the server, but the
important thing is that the smtp-server doesnt close the socket.
The while-loop will now continue to loop until "maximum execution time"
(30 secs in my case)
The feof() -never- returns true in php 4.3.0 but does so in 4.2.3.


And this is exacly my problem.
(In my "real" case I dont connect to a smtp-server but the scenario is
the same.)

Regards
/Bjarne

------------------------------------------------------------------------

[2003-01-25 01:00:03] [EMAIL PROTECTED]

No feedback was provided for this bug for over 2 weeks, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".

------------------------------------------------------------------------

[2003-01-09 04:33:57] [EMAIL PROTECTED]

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.

------------------------------------------------------------------------

[2003-01-09 04:23:45] [EMAIL PROTECTED]

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.

------------------------------------------------------------------------

[2003-01-09 04:05:25] [EMAIL PROTECTED]

The nature of non-blocking sockets means that your script must always
be prepared to handle a false or zero length return from fgets/fread,
so I'm not worried about that aspect.
However, the feof() does seem to be a problem.
Looking into it...

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/21485

-- 
Edit this bug report at http://bugs.php.net/?id=21485&edit=1


-- 
PHP Documentation Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to