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
(PHP 4 >= 4.1.0, PHP 5)
socket_write — ソケットに書き込む
説明
$socket
, string $buffer
[, int $length = 0
] )
関数 socket_write() は、
buffer の内容をソケット
socket に書き込みます。
パラメータ
-
socket -
-
buffer -
書き込まれるバッファ。
-
length -
オプションのパラメータ
lengthで、 ソケットに書き込むバイト数を指定することが可能です。 この値がバッファの長さより大きい場合、自動的にバッファのサイズに切り詰められます。
返り値
ソケットへの書き込みに成功したデータのバイト数を返します。失敗した場合に FALSE を返します。
エラーコードは socket_last_error()
を用いて取得することができ、この値を socket_strerror()
に渡すことでエラー情報を文字列で取得可能です。
注意:
socket_write() がゼロを返すことも十分ありえます。 これは、書き込むデータが存在しなかったことを意味します。 エラーをチェックするために
FALSEかどうかを調べる際には、必ず === 演算子を使用しましょう。
注意
注意:
socket_write() は、バッファの内容を必ずしもすべて 書き込むとは限りません。ネットワークバッファの状態にもよりますが、 たとえ 1 バイトだけ書き込まれたのであったとしても、それはエラーではなく正常な動作です。 そのため、データがすべて書き込まれたのかどうかに注意する必要があります。
参考
- socket_accept() - ソケットへの接続を許可する
- socket_bind() - ソケットに名前をバインドする
- socket_connect() - ソケット上の接続を初期化する
- socket_listen() - ソケット上で接続待ち(listen)する
- socket_read() - ソケットから最大バイト長まで読みこむ
- socket_strerror() - ソケットエラーの内容を文字列として返す
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;
}
?>
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.
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.
"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
}
?>
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 ;)
