第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP socket_write 失敗僅在下次調(diào)用時返回錯誤

PHP socket_write 失敗僅在下次調(diào)用時返回錯誤

PHP
楊魅力 2023-09-08 21:35:52
我正在嘗試通過 PHP 套接字發(fā)送數(shù)據(jù),客戶端是 Arduino 設(shè)備,當我多次發(fā)送時它接收數(shù)據(jù)正常,但是如果我重置客戶端(Arduino 設(shè)備),它會在幾秒鐘內(nèi)重新啟動,它說連接到 PHP 套接字,然后當我想再次發(fā)送數(shù)據(jù)時,它會socket_send()默默地失敗,PHP在第一個實際錯誤時不會返回錯誤,只有在我第二次嘗試(并失?。r,才會返回錯誤(“零”socket_send()發(fā)送的字節(jié)數(shù)”)。收到此錯誤時,我創(chuàng)建另一個錯誤socket_accept()并成功發(fā)送消息。什么可能導致這種情況?我希望它能夠正確檢測丟失的連接,以便我可以在需要時重新發(fā)送數(shù)據(jù)。感覺就像它向舊連接發(fā)送數(shù)據(jù),并且只有在第二次嘗試時才意識到,這可能嗎?這可以通過 解決嗎socket_select()?我很難理解它的作用。澄清:如果客戶端重新啟動并再次連接,則向其發(fā)送數(shù)據(jù)將返回int,然后返回false, false, false(除非我取消設(shè)置$accept并再次執(zhí)行 a socket_accept())。如果客戶端保持離線狀態(tài),則發(fā)送始終返回int, int, int。 int是發(fā)送的字符串的大小。$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");// reuse any existing open port to avoid errorsocket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");$result = socket_listen($socket) or die("Could not set up socket listener\n");    do{    if(!isset($accept)){        echo "\nwaiting for clients";        $accept = @socket_accept($socket) or die("Could not accept incoming connection");        echo "\nclient connected";    }        // memcached will return a message here like: "my message\r\n"    $message_to_send = $memcached->get('my_socket_message');        if($message_to_send!=''){        echo "\nsending: ".$message_to_send;            $total_data_sent = @socket_send($accept, $message_to_send, strlen($message_to_send), MSG_EOR);            // if data was not send (sent to an old connection ?!)...        // then clear $accept, so a new connection is accepted        // and keep the my_socket_message variable, so message is sent again        if($total_data_sent === false){            echo "\nSEND FAILED, will retry message: ".$message_to_send;            unset($accept);        } else {            $memcached->delete('my_socket_message');        }        }    } while (true);
查看完整描述

2 回答

?
鴻蒙傳說

TA貢獻1865條經(jīng)驗 獲得超7個贊

我進行了一些實驗并能夠重現(xiàn)該問題。這是我的解決方案(也許不是最好的方法,但有效):


@socket_send($accept, $message_to_send, strlen($message_to_send), MSG_EOR);

$dataSent = @socket_write($accept, '', 0);


    if ($dataSent === false) {

        unset($accept);

        // ...

編輯

我想出了一個更簡潔的解決方案。我們只是做函數(shù)socket_send應(yīng)該做的事情。返回false或int接收到的字節(jié)數(shù)。


在接收端,您只需解碼消息 ( $data) 并發(fā)strlen回$data['payload']??蛻舳艘部梢则炞C它是否已收到這樣的所有數(shù)據(jù)。為此,只需與strlen進行比較即可。如果你真的很偏執(zhí),你也可以實現(xiàn)一些校驗和。$data['payload']$data['length']


服務(wù)器使用的代碼send而不是socket_send:


function send($client, $message) {

    $messageLength = strlen($message);


    $data = [

        'length' => $messageLength,

        'payload' => $message

    ];

    $jsonData = json_encode($data);


    try {

        @socket_send($client, $jsonData, strlen($jsonData), MSG_EOR);

        $response = @socket_read($client, 1024);


        if (intval($response) !== $messageLength) {

            return false;

        }

    } catch (Exception $e) {

        return false;

    }

    

    return $response;

}

盡管這可行,但我認為 TCP 正是這樣做的——確保數(shù)據(jù)已被接收。也許我們?nèi)匀蝗鄙僖恍〇|西。


查看完整回答
反對 回復(fù) 2023-09-08
?
湖上湖

TA貢獻2003條經(jīng)驗 獲得超2個贊

這就是我最終使用的,看起來效果很好。它等待來自客戶端的回復(fù)/確認,如果沒有收到確認,則message_to_send保留,連接被清除,在下一個循環(huán)中它重新連接并重試發(fā)送現(xiàn)有的message_to_send.


$total_data_sent = @socket_send($accept, $message_to_send, strlen($message_to_send), MSG_EOR);


// set a timeout for waiting a reply, in this case 500 milliseconds

socket_set_option($accept, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>0, "usec"=>500000));


// read a reply, which should be "ok" (text sent by client)

$reply = socket_read($accept, 1024);


// if reply was not "ok", then unset the connection and will reconnect on next loop

if($reply != "ok"){

    unset($accept);

}


// if reply was "ok", then clear this message as it was successfuly sent

if($reply == "ok"){

    unset($message_to_send);

}


查看完整回答
反對 回復(fù) 2023-09-08
  • 2 回答
  • 0 關(guān)注
  • 136 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號