Hallo,
ich beschäftige mich die letzte Zeit sehr mit Sockets, bin aber an einem
Punkt angekommen, bei dem ich gerade nicht weiterkomme.
Mein erstes Problem ist die Fehlerbehandlung. Dazu erstmal mein
Serverscript (zusammengekürzt): http://pastebin.com/f5e00d4fa
Wie kann ich (zuverlässig!) rausfinden, ob ein Socket geschlossen
ist/wurde? Weder ($data === '') noch ($data === false) funktionieren
zuverlässig, denn mal erhalte ich einen leeren String, mal false, wenn
eine Verbindung vom Client geschlossen wurde. (Das, was über der
if-Abfrage als Kommentar steht, habe ich aus den Kommentaren im PHP-Manual.)
Mein zweites Problem ist folgendes: Wie man an dem Serverscript sieht,
benutze ich unserialize(), um die Daten wieder in eine Form zu bekommen,
in der ich mit ihnen arbeiten kann. Hier mein Client(-test-)script:
http://pastebin.com/f3c55971c
Das Problem: Lasse ich das erste sleep(2) weg, empfängt der Server beide
"Pakete" zusammen. Natürlich wird dann nur eins von beiden von
unserialzie() bearbeitet, das Zweite wird ignoriert. "Otherwise you can
use \r, \n, or \0 to end reading (depending on the type parameter, see
below)." - steht im PHP Manual. socket_read() bricht bei \0 aber
offensichtlich *nicht* ab, sondern liest einfach alle Daten, die im
Puffer sind, egal ob und wo ein \0 steht. (Es existiert dazu auch schon
ein Bugreport, allerdings in Zusammenhang mit PHP_NORMAL_READ, wo \r und
\n ignoriert werden, wenn der Client die Daten "zu schnell" sendet.)
Dann habe ich auch noch eine Frage: "Note: socket_write() does not
necessarily write all bytes from the given buffer. It's valid that,
depending on the network buffers etc., only a certain amount of data,
even one byte, is written though your buffer is greater. You have to
watch out so you don't unintentionally forget to transmit the rest of
your data." Bis jetzt wurden immer alle Daten komplett gesendet. Wie
ernst soll ich diese Aussage also nehmen? Ich hatte noch nie das
Problem, dass weniger Daten geschrieben (gesendet) wurden, als ich an
die Funktion übergeben hatte. Wenn ich eine Funktion einbaue, die dafür
sorgt, dass auf jeden Fall alles gesendet wird (while ($bytes_written <
$data_length) socket_write(...usw...)), besteht dann nicht auch wieder
die Gefahr, dass der Server erst den einen Teil und erst im nächsten
Schleifendurchlauf den zweiten Teil empfängt? Dann würde die Sache mit
unserialize() auch nicht mehr funktionieren...
Hilfe suchend und im Voraus danke sagend,
Micha
