国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

關(guān)于粘包的問(wèn)題

jorry橋

workerman當(dāng)然是完整的沒(méi)有粘包問(wèn)題,但是我使用自己的程序接收workerman發(fā)送過(guò)來(lái)的信息時(shí)出現(xiàn)了這個(gè)問(wèn)題,即從workerman發(fā)送的一條一條的信息變成了一整條的了,這個(gè)有一個(gè)通用的解決方案嗎,我使用的是文本傳遞協(xié)議。。。求解

4908 5 0
5個(gè)回答

jorry橋

使用接收程序如下:

while ( $buf = stream_socket_recvfrom ( $new_conn, 65535 ) ) {
    $all_buffer .= $buf;
    if($buf === "\n") {
        break;
    }
    return $all_buffer;
}

接收一個(gè)一個(gè)字符接收是為了檢查邊界
結(jié)果很明顯會(huì)有粘包的現(xiàn)象,因?yàn)橐幌伦幼x那么多,而且接收的數(shù)據(jù)實(shí)際是上多條的,
在這里判斷邊界其實(shí)是沒(méi)有意義的,那么怎么辦呢:

while ( $buf = stream_socket_recvfrom ( $new_conn, 1 ) ) {
    $all_buffer .= $buf;
    if($buf == "\n") {
        break;
    }
    return $all_buffer;
}

我就一個(gè)一個(gè)的接收,這總行了吧,結(jié)果又是沒(méi)什么:
沒(méi)有了粘包問(wèn)題,但接收的數(shù)據(jù)把我的整條信息拆開(kāi)了,這又不是我想要的,為什么會(huì)在接收到 "\n"之前我的循環(huán)就跳出了呢?
這得考慮socket數(shù)據(jù)傳輸?shù)奶匦粤耍@的規(guī)則是我們接收和發(fā)送定義的,而它自己的規(guī)則對(duì)我們來(lái)說(shuō)沒(méi)有實(shí)際的處理意義,即stream_socket_recvfrom返回來(lái)的可能為空。沒(méi)能等到"\n"就已經(jīng)跳出了。

最后walkor提供了以下方法:

$all_buffer = '';
while(1)
{
    $buf = stream_socket_recvfrom ( $new_conn, 1 );
    if(empty($buf))
    {
        if(feof($buf))
        {
            break;
        }
        continue;
    }
    $all_buffer .= $buf;
    if($buf == "\n")
    {
        break;
    }
}
return $all_buffer;

問(wèn)題解決。

  • 暫無(wú)評(píng)論
walkor 打賞

處理方法類(lèi)似,根據(jù)協(xié)議判斷請(qǐng)求邊界。
例如協(xié)議是 json+回車(chē)

客戶端應(yīng)該類(lèi)似這樣讀

$client = stream_socket_client('tcp://ip:port');
$all_buffer = '';
while(1)
{
   // 每次讀一個(gè)字節(jié),因?yàn)槊總€(gè)字節(jié)都有可能是代表數(shù)據(jù)的結(jié)束的回車(chē)字符
   $buf = stream_socket_recvfrom($client, 1);
   // stream_socket_recvfrom 可能返回空,比如$client是非阻塞的,或者被信號(hào)打斷、斷開(kāi)、超時(shí)等
   if(empty($buf) && $buf != '0')
   {
        // 鏈接斷開(kāi)就跳出
        if(feof($buf))
        {
           break;
        }
        // 繼續(xù)
        continue;
   }
    // 拼接數(shù)據(jù)
    $all_buffer .= $buf;
    // 是請(qǐng)求邊界就跳出
    if($buf == "\n")
    {
        break;
    }
}

當(dāng)然上面的協(xié)議簡(jiǎn)單,但是由于是一個(gè)字節(jié)一個(gè)字節(jié)的讀,對(duì)性能有一點(diǎn)點(diǎn)的損耗

如果對(duì)性能要求非常非??量?,可以采用 類(lèi)似 包長(zhǎng)+包體 的協(xié)議傳輸

  • 暫無(wú)評(píng)論
walkor 打賞

額,jorry已經(jīng)回答了

  • 暫無(wú)評(píng)論
一路向北

看了一下代碼。是不是

if(empty($buf))
{
// 鏈接斷開(kāi)就跳出
if(feof($buf))
{
break;
}
// 繼續(xù)
continue;
}

這樣就把字符中的空格給抹掉了?

  • 暫無(wú)評(píng)論
walkor 打賞

應(yīng)該不會(huì)抹掉空格,但是會(huì)抹掉 '0' 字符,得加個(gè)判斷

if(empty($buf) && $buf != '0')
{
// 鏈接斷開(kāi)就跳出
if(feof($buf))
{
break;
}
// 繼續(xù)
continue;
}

  • 暫無(wú)評(píng)論
年代過(guò)于久遠(yuǎn),無(wú)法發(fā)表回答
??