PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [PHP]: Streams funktionieren nicht so wie ich will


mf_2
2007-09-26, 13:11:57
Hallo,

Ich habe lokal einen Mailserver laufen. Auf diesem führe ich mit telnet folgende Kommandos aus:

HELO
EHLO
QUIT

Sowohl nach HELO als auch nach EHLO bekomme ich eine Rückgabe. Bei Verbindungsaufbau bekommt man eine Willkommensnachricht.

Wenn ich nun unter PHP so die Verbindung aufbaue:
$sock = fsockopen("127.0.0.1", 25, $errno, $errstr, 30);

und mir $sock ausgeben lasse (echo fgets($sock)."<BR>";), habe ich ebenfalls die Willkommensnachricht.
Nun sende ich das HELO: fwrite($sock, "HELO".chr(10).chr(13));
und wieder eine Ausgabe: echo fgets($sock)."<BR>";
Das klappt auch noch. Wenn ich nun aber nochmal HELO sende, oder auch EHLO, oder QUIT oder sonstwas, bekomme ich immer den Fehler 503 - Bad sequence of commands.
Ich 'vermute', dass mein CRLF (Codes 10 und 13) nicht richtig interpretiert wird und daher das Zeilenende nach der ersten Anweisung nicht sauber ist, was zur Folge hat, dass jede (wie auch immer lautende) Folgeanweisung zum Scheitern verurteilt ist.
Wie bekomme ich nun ein sauberes Zeilenende hin? Laut PHP Manual ist ein CRLF genau das, was erwartet wird.
Ohne diese chr(10).chr(13) funktioniert es garnicht.
Wisst ihr da weiter?

mf_2
2007-09-26, 13:23:52
Jetzt geht es, \r\n statt dem chr(10).chr(13) haben geholfen. Aber: Wie bekomnme ich die ganze Ausgabe des Kommandos? fgets() gibt immer nur eine Zeile aus. Das funktioniert auch wunderbar für die Willkommensnachricht oder HELO, aber spätestens bei EHLO beisst das ins Gras.

mf_2
2007-09-26, 16:56:21
Weiss denn keiner was? Ich verzweifle hier noch? Gibts vielleicht eine Art Puffer die ich der fputs() Anweisung noch mitgeben kann?

Coda
2007-09-26, 17:01:53
Schau dir doch mal mit Wireshark an was genau gesendet wird.

mf_2
2007-09-26, 17:21:31
Wireshark zeigt mir ein haufen Zeug an, aber mit dem Filter "ip.addr == 127.0.0.1" kommt garnichts. Sowohl der Mailserver als auch das PHP-Script laufen lokal auf einem Mercury 32 Mailserver bzw. einem XAMPP Apache 2 Server.
Die Mercury 32 Statusfenster zeigen mir aber einen erfolgreiche Verbindung an und listen mir sogar die Befehle, welche das PHP-Script abgesetzt hat.

The_Invisible
2007-09-26, 18:06:51
wie wärs mit:


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


vielleicht noch ein paar sleep() funktionen dazwischen wenn der mailserver langsam antwortet.

mfg

mf_2
2007-09-26, 21:50:18
Ohne sleep gehts nicht (das Beispiel steht nämlich fast überall, z.B. auch in der PHP Doku auf php.net), aber morgen werde ich es mal mit sleep ausprobieren, vielen Dank schonmal!
Aber wenn jemand noch eine zuverlässigere Lösung weiss, dann bitte auch posten.

mf_2
2007-09-27, 08:11:17
sleep() hilft, vielen Dank!
Ich habe jetzt die fgets() Anweisungn durch stream_get_contents() ersetzt und diese holt mir jetzt die ganzen Zeilen einer mehrzeiligen Rückgabe. Aber der sleep() ist etwas unsauber finde ich. Lieber wäre mir so etwas:


$sock = fsockopen("127.0.0.1", 25, $errno, $errstr, 30);
stream_set_blocking($sock,0);
fputs($sock, "QUIT\r\n");
$sockarray=array($sock);
while($dummy!=1)
{
if(stream_select($sockarray)!=FALSE)
{
fwrite($fp,"test");
echo stream_get_contents($sock)."<BR>";
$dummy=1;
}
}
fclose($sock);


Das wäre also eine Anweisung,die besagt "Warte bis Daten im Stream stehen (stream_select != FALSE) und hole sie dann via stream_get_contents()".
Das mit dem Array mit einem Element ist deswegen, weil die stream_select() Funktion ein Array will und nicht nur einen einfachen Stream. Siehe hier:
http://de2.php.net/manual/de/function.stream-select.php

Wisst ihr, wie ich so etwas zum Laufen bekomme?
Wenn ich den Blocking Mode des Streams aktiviere, scheitert das Script an den fgets() und beendet sich auch nie.