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)匀蝗鄙僖恍〇|西。

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);
}
- 2 回答
- 0 關(guān)注
- 136 瀏覽
添加回答
舉報