我收到一个套接字响应,其中前4个字节是一个压缩的int,表示要接收的消息的最后部分。我们通过MSG_WAITALL
接收它,它只在关闭连接之前收到一定数量的字节。 PHP手册说这是正常的“如果信号被捕获”。我如何获得完整的消息,$i["val"]
长?
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_connect($sock , $server , 4656);
socket_recv($sock, $i, 4, MSG_WAITALL);
$i=unpack('Nval', $i);
socket_recv($sock, $buf, $i["val"], MSG_WAITALL);
具体来说它只读取2916bytes。如果$i["val"]
小于该值,则读取正确,否则最大值为2916字节。
即使我循环,它也无法正确读取,除非我一次以1字节循环,我认为这不是正确的方法。这是一个2045b /循环的循环。
$len=$i[val];
echo 'Total Len: ' . $len . PHP_EOL;
if($len>=2045){
$loops=floor($len/2045);
echo 'Total Loops: ' . $loops . PHP_EOL;
$last_loop=$len-(2045*$loops);
echo 'Last Loop: ' . $last_loop . PHP_EOL;
for($x=1; $x<=$loops; $x++){
socket_recv($sock, $buf, 2045, MSG_WAITALL);
$reply.=$buf;
}
socket_recv($sock, $buf, $last_loop, MSG_WAITALL);
$reply.=$buf;
}else{
socket_recv($sock, $buf, $len, MSG_WAITALL);
$reply.=$buf;
}
echo 'Total Received: ' . strlen($reply) . PHP_EOL;
答案 0 :(得分:0)
以下是一些未经测试的代码:
<?php
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_connect($sock, $server, 4656);
$len = 0;
$reply = '';
do {
$status = socket_recv($sock, $buffer, 2048, 0);
if (!$len) {
$i = unpack('Nval', substr($buffer, 0, 4));
$len = $i['val'];
$buffer = substr($buffer, 4);
echo 'Total Len: ' . $len . PHP_EOL;
}
$reply .= $buffer;
if ($status === false) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
echo 'socket: [' . $errorcode . ']' . $errormsg . PHP_EOL;
break;
}
} while (strlen($reply) < $len);
echo 'Total Received: ' . strlen($reply) . PHP_EOL;
?>