Some clients (Flash's XMLSocket for example) won't fire a read event until a new line is recieved.
<?php
/*
* Write to a socket
* add a newline and null character at the end
* some clients don't read until new line is recieved
*
* try to send the rest of the data if it gets truncated
*/
function write(&$sock,$msg) {
$msg = "$msg\n\0";
$length = strlen($msg);
while(true) {
$sent = socket_write($sock,$msg,$length);
if($sent === false) {
return false;
}
if($sent < $length) {
$msg = substr($msg, $sent);
$length -= $sent;
print("Message truncated: Resending: $msg");
} else {
return true;
}
}
return false;
}
?>
socket_write
(PHP 4 >= 4.1.0, PHP 5)
socket_write — Écrit dans une socket
Description
socket_write() écrit dans la socket socket les données du buffer buffer.
Liste de paramètres
- socket
-
- buffer
-
Le buffer à écrire.
- length
-
Le paramètre optionnel length peut spécifier explicitement la taille des données qui doivent être écrites. Si cette longueur est plus grande que la taille du buffer, elle sera ramenée automatiquement à la taille du buffer lui-même.
Valeurs de retour
socket_write() retourne le nombre d'octets qui ont pu être écrits dans la socket ou FALSE si une erreur survient. Le code d'erreur généré peut être obtenu en appelant la fonction socket_last_error(). Ce code d'erreur peut être passé à la fonction socket_strerror() pour obtenir un message d'erreur, humainement lisible.
Note:
Il est parfaitement valide pour socket_write() de retourner zéro, ce qui signifie qu'aucun octet n'a été écrit. Soyez bien sûr d'utiliser l'opérateur === pour comparer le retour de la fonction avec FALSE, et détecter un cas d'erreur.
Notes
Note:
socket_write() n'écrit pas nécessairement tous les octets du buffer fourni. Il est valide que, suivant certaines configuration de buffer réseau, seulement une certaine quantité de données, même un octet, soit écrit, y compris si votre buffer est plus grand. Vous devez alors vous assurer que vous n'avez pas oublié de transmettre le reste de vos données.
Voir aussi
- socket_accept() - Accepte une connexion sur une socket
- socket_bind() - Lie un nom à une socket
- socket_connect() - Crée une connexion sur une socket
- socket_listen() - Attend une connexion sur une socket
- socket_read() - Lit des données d'une socket
- socket_strerror() - Retourne une chaîne décrivant un message d'erreur
Here we have the same function to write a socket but with improved performance.
If the messager are not larger, they will be written entirely with a single socket_write() call. And is not needed to call the substr() function for the first bucle.
<?php
$st="Message to sent";
$length = strlen($st);
while (true) {
$sent = socket_write($socket, $st, $length);
if ($sent === false) {
break;
}
// Check if the entire message has been sented
if ($sent < $length) {
// If not sent the entire message.
// Get the part of the message that has not yet been sented as message
$st = substr($st, $sent);
// Get the length of the not sented part
$length -= $sent;
} else {
break;
}
}
?>
"socket_write() does not necessarily write all bytes from the given buffer."
So I wrote the following code to correctly write message to the socket
<?php
$message="Message to sent";
$len = strlen($message);
$offset = 0;
while ($offset < $len) {
$sent = socket_write($socket, substr($message, $offset), $len-$offset);
if ($sent === false) {
// Error occurred, break the while loop
break;
}
$offset += $sent;
}
if ($offset < $len) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
echo "SENDING ERROR: $errormsg";
} else {
// Data sent ok
}
?>
Hi,
if you got same problems like i have
<?php
@socket_write($xd, "Good Bye!\n\r");
@socket_shutdown($xd, 2);
@socket_close($xd);
?>
wont'tx send "Good Bye!\n\r" to the opened socket.
but if you put a
usleep or something like echo "";
between write and shutdown its working.
If you connect to a Server in a way like you do with telnet or some similar protokoll you may have problems with sending data to the server. I found out that at some servers there is a different between:
<?php
socket_write ($my_socket, $line, strlen ($line));
socket_write ($my_socket, "\r\n", strlen ("\r\n"));
?>
witch worked at least, and
<?php
socket_write ($my_socket, $line."\r\n", strlen ($line."\r\n"));
?>
wich made the server stop sending any data.
I hope this helps to save a lot of time. I needed about two days to find out, that this was the problem ;)
from http://www.manualy.sk/sock-faq/unix-socket-faq-2.html
read() is equivalent to recv() with a flags parameter of 0. Other values for the flags parameter change the behaviour of recv(). Similarly, write() is equivalent to send() with flags == 0.
