2

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
halfer
  • 19,824
  • 17
  • 99
  • 186
Cyril N.
  • 38,875
  • 36
  • 142
  • 243

1 Answers1

2

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);
hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Thank you for your reply. I made a mistake, it was 25, SMTP. The problem is when connecting to an SMTP server, some answer one line directly, wait a few seconds and then resend data. You have to wait for that, which is my issue. (before sending other data.) – Cyril N. Feb 18 '15 at 10:10
  • You need to implement SMTP. (Or use an exisiting PHP client, probably this: http://pear.php.net/package/Net_SMTP) – hek2mgl Feb 18 '15 at 10:19
  • Yeah you put me on the right track! There was a trick in the SMTP protocol that I've found reading the source of PHPMailler :) Copy/paste this code (http://pastebin.com/YeRDYkgK) and I'll accept your answer (if you want! :) ) – Cyril N. Feb 18 '15 at 10:32