无法在 Web 套接字中取消屏蔽多个帧

Posted

技术标签:

【中文标题】无法在 Web 套接字中取消屏蔽多个帧【英文标题】:Unable to unmask more than one frame in web socket 【发布时间】:2018-10-19 07:18:28 【问题描述】:

我在 php 服务器中通过 socket_recv 接收帧时遇到问题。当我一次从客户端发送超过 1 条消息时出现问题(例如 for 循环)

如果循环是 10 倍,我在 decMessages 中只返回 1 并且当我打印有效负载时,它一次只显示 2 条消息。

function unmask($payload) 


$tempCount=0;
$decMessages = Array();  
do 
 // This should be running until all frames are unmasked and added to $decMessages Array 
    $tempCount++;
    $length = ord($payload[1]) & 127;
    $temp_variable = 0;
    if($length == 126) 
      $temp_variable = 4;   
      $masks = substr($payload, 4, 4);
      $data = substr($payload, 8);
      $len = (ord($payload[2]) << 8) + ord($payload[3]);
    elseif($length == 127) 
      $temp_variable = 14;  
      $masks = substr($payload, 10, 4);
      $data = substr($payload, 14);
      $len = (ord($payload[2]) << 56) + (ord($payload[3]) << 48) +
          (ord($payload[4]) << 40) + (ord($payload[5]) << 32) +
          (ord($payload[6]) << 24) +(ord($payload[7]) << 16) +
          (ord($payload[8]) << 8) + ord($payload[9]);
    else         
      $temp_variable = 6;       
      $masks = substr($payload, 2, 4);
      $data = substr($payload, 6);
      $len = $length;
    

    $payload = '';
    for ($i = 0; $i < $len; ++$i)     
      $payload .= $data[$i] ^ $masks[$i%4];
    
    echo "This is payload".$payload."\n\r";
    echo "This is Count ".count($decMessages)."\n\r";
    echo "This is temp ".$tempCount."\n\r";

    $decMessages[] = $payload;


    $payload = substr($payload, $len+$temp_variable, strlen($payload));     

while (($len < strlen($data)) && $tempCount<10);

//echo "\n" . count($decMessages) . "\n";

return $decMessages;

【问题讨论】:

我猜你的 while 循环条件没有按预期运行。试图从阅读该代码中找出原因非常困难。我会从 while 条件开始,然后从那里开始工作。 您能否提供一个 $payload 示例以便可以运行代码 sn-p? 即使临时计数达到2,while条件也会自动中断,然后我得到的输出是奇怪的字符 对于有效载荷,我使用了超过 141 个字符的字符串@Dag Sondre 由于 Nagle 的算法,我正在尝试从 IoT 设备发送数据并在 php 服务器上接收它,我将两个以上的数据包放在一起,我想将其取消屏蔽并在浏览器上显示 【参考方案1】:

您已将 $payload 变量的数据替换为未屏蔽的数据。我添加了新的 $text 变量。

function unmask($payload) 

$tempCount=0;
$decMessages = Array();  
do 
 // This should be running until all frames are unmasked and added to $decMessages Array 
    $tempCount++;
    $length = ord($payload[1]) & 127;
    $temp_variable = 0;
    if($length == 126) 
      $temp_variable = 4;   
      $masks = substr($payload, 4, 4);
      $data = substr($payload, 8);
      $len = (ord($payload[2]) << 8) + ord($payload[3]);
    elseif($length == 127) 
      $temp_variable = 14;  
      $masks = substr($payload, 10, 4);
      $data = substr($payload, 14);
      $len = (ord($payload[2]) << 56) + (ord($payload[3]) << 48) +
          (ord($payload[4]) << 40) + (ord($payload[5]) << 32) +
          (ord($payload[6]) << 24) +(ord($payload[7]) << 16) +
          (ord($payload[8]) << 8) + ord($payload[9]);
    else         
      $temp_variable = 6;       
      $masks = substr($payload, 2, 4);
      $data = substr($payload, 6);
      $len = $length;
    

    $text = '';
    for ($i = 0; $i < $len; ++$i)     
      $text .= $data[$i] ^ $masks[$i%4];
    
    echo "This is text ".$text."\n\r";
    echo "This is Count ".count($decMessages)."\n\r";
    echo "This is temp ".$tempCount."\n\r";

    $decMessages[] = $text;    

    $payload = substr($payload, $len+$temp_variable, strlen($payload));     

while (($len < strlen($data)) && $tempCount<10);

//echo "\n" . count($decMessages) . "\n";

return $decMessages;

【讨论】:

以上是关于无法在 Web 套接字中取消屏蔽多个帧的主要内容,如果未能解决你的问题,请参考以下文章

websocket客户端数据包取消框架/取消屏蔽

Web 套接字、长轮询、服务器发送事件和永久帧之间有啥区别?

在聊天应用程序中使用 Web 套接字 Api 无法正确显示图像

多个独立的 websockets 连接

一次可以打开的 Web 套接字客户端的数量

为啥我无法通过 Web 套接字连接获得 HubCallerContext 用户?