Page 1 of 1

[SOLVED] fsockopen(), fgets() and unknown EOF

Posted: Mon May 01, 2006 5:54 pm
by Chris Corbyn
Hello!

If I open a connection to an SMTP server and send out commands via fwrite() to a handle opened by fsockopen() I can read the results using fgets() on the handle. Good.

This is working fine for reading back a single line in a response but when attempting the following the script just hangs.

Code: Select all

$data = "";
while (!feof($handle))
{
    $data .= fgets($handle);
}

echo $data;
My only guess is that the response does not contain an EOF, even though there are clearly only X number of lines returned. I'm at a loss as to how to read all the data here.

On a response that through telnet I saw 5 lines returned I manually wrote code to run fgets() 5 times on the handle and it worked.... when running it for a 6th time the script hangs like before.

I've tried stream_get_contents() and this has the same outcome. Has anybody got any experience of working out how many times fgets() needs to be called? Is it even anything to do with the EOF?

Cheers.

Posted: Mon May 01, 2006 5:57 pm
by feyd
read Y number of bytes via fgets() or fread() until you get zero bytes in length returned. :)

Posted: Mon May 01, 2006 6:03 pm
by Chris Corbyn
feyd wrote:read Y number of bytes via fgets() or fread() until you get zero bytes in length returned. :)
I tried this previously with the hanging occuring again... I'm wondering if using fread($handle, 1) repeatedly might do the same when we go too far:

Code: Select all

$data = "";
while(true)
{
    $tmp = fgets($handle);
    if (empty($tmp)) break;
    else $data .= $tmp;
}
I shall give it a shot and see what happens :)

Posted: Mon May 01, 2006 6:12 pm
by Chris Corbyn
Maybe I'm just being dumb here but do you mean this?

Code: Select all

$data = "";
while ($tmp = fread($handle, 1))
{
    if (strlen($tmp) > 0) $data .= $tmp;
    else break;
}
That hangs too.... Hmm...

Posted: Wed May 03, 2006 4:41 am
by Chris Corbyn
*Bump*

Sorry... at a loss here :( Even just trying to read one byte too far causes the script to hang but if there's no EOF how do I work out where I am?

Lets say I do this (but in fsockopen() not telnet).

Code: Select all

telnet smtp 25
Trying 192.168.2.12...
Connected to smtp.
Escape character is '^]'.
220 XXXX.sch.uk, Authorised Clients Only ESMTP
EHLO iris
250-XXXX.sch.uk, Authorised Clients Only
250-AUTH LOGIN CRAM-MD5 PLAIN
250-AUTH=LOGIN CRAM-MD5 PLAIN
250-STARTTLS
250-PIPELINING
250 8BITMIME
After I typed EHLO, 6 lines were returned.... I can see that, you can see that, but how can PHP see that? There's apparently no EOF in what's returned neither.... sounds impossible right? But then how does telnet know where to stop reading?

Oh... I see a pattern actually. Notice the last line of output excludes the hyphen after the status number? Maybe that's how you know you're on the last line? I don't remember seeing that in the RFC but I'll have another look.

Posted: Wed May 03, 2006 4:46 am
by Chris Corbyn
OK that'll teach me to do my research a little better!!!
In a multiline reply all lines except the last have a hyphen after the numeric reply code.