phpsocketsfsockopen

fget over server, how to read until end of current transmission?


I'm writing a tool that connects to a server, sends request, read response, and send other commands.

The problem is that the response the server send can vary in terms of lines (it's always at least one line, but can be 3, 5 lines), and he can send one line, wait a few seconds, then send others lines.

Is there a way to read all the incoming data until they stop? Maybe I have to change for sockets?

Here are my tries :

$fp = fsockopen("www.example.com", 25, $errno, $errstr, 30);

-

while(fgets($fp, 1024)) {} // hangs

-

fgets($fp, 4096); // works, but doesn't get the multiple lines

-

while(!feof($fp)){
    fgets($fp, 1024);
}
// hangs

-

while(($c = fgetc($fp))!==false) {
   var_dump($c);
}
// hangs

Solution

  • You are using a TCP connection. A TCP connection will stay open unless one of the communication partners explicitly closes it.

    This means

    while(!feof($fp)) {
        fgets($fp);
    }
    

    will hang forever unless the server closes the connection after transfer. (It seems that the remote server does not). This applies to while(fgets($fp, 1024)) {} as well.

    The other option would be that the client (your PHP script) closes the connection. This can be done safely only if the client knows the size of the message and can decide when all the bytes has been sent.

    Implementing this is a protocol feature, in HTTP for example the content-length header is used.

    Having that you connecting to port 25, I assume that you are speaking with an SMTP server. SMTP manages the message length as a protocol feature. You'll need to implement the SMTP protocol.


    About:

    $message = fgets($fp, 4096);
    

    It "works" only if it is sure that the message will never exceed 4096 bytes. The newlines are still in the result, you simply would need to

    $lines = explode("\n", $message);