解决这个问题如下
问题:当接收使用的WebSocket的东西,如socket_recv($socket,$buffer,5000,0);
你可能不会得到在一次调用完整的数据资料的长字节,则需要再次调用socket_recv($socket,$buffer,5000,0);
。
例如,假设我们用JS(socket.send)从浏览器向websocket发送了8000字节的数据。在服务器端,我们将使用socket_recv来获取消息。但是,我们可能只会首先收到大约4000个字节的数据,并且可能需要再次调用socket_recv才能获得剩余的4000个字节。
现在在我的原始代码中,我曾经调用socket_recv来取消屏蔽数据后,调用函数“unmask”。这将适用于收到的第一组消息。但对于下一组消息,“解除掩码”功能将尝试提取新的掩码并应用该掩码。这是错误,因为消息是以前消息的延续,并且Mask不会更改。解决方案是保持第一条消息的掩码,并检查下一条消息是否继续。这可以通过检查消息的第一位来完成。
$fin=ord($payload[0]) & 0x77;
如果$翅片1的消息是一个新的消息,如果不是它是前一消息的延续。在($ fin!= 1)的情况下,您需要使用之前消息的掩码来揭露消息。不要忘记,因为您需要再次使用mask的值,您需要在函数外部定义它并使其成为全局的。
我已经提供了以下新旧代码供您参考。我希望这是正确的解决方案,但请随时添加任何内容或让我知道我是否在任何地方出错。
我原来的取消屏蔽功能:
function unmask($payload) {
$length = ord($payload[1]) & 127;
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
$firstcode=substr($payload, 1, 1);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
$firstcode=substr($payload, 1, 1);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
$firstcode=substr($payload, 1, 1);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}
更新功能:
function unmask($payload,$masks) {
global $masks;
$fin=ord($payload[0]) & 0x77;
if($fin!=1){
$data=substr($payload,0);
$text='';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}else{
$length = ord($payload[1]) & 127;
Echo "Mask functiion Payload Lenght".$length."\n";
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i]^$masks[$i%4];
}
return $text;
}
}
套接字=的WebSockets –
由于错误代码为0,但我想我没有得到完整的数据但数据是分散的。现在,我真的被困在如何揭露碎片数据。我可以取消第一帧,但无法屏蔽下一帧。 – user2288650