我已經使用套接字在 C 中實作了一個 websocket 客戶端庫。它與許多 websocket 服務器一起正常作業。但是當我嘗試與我的客戶服務器之一連接時,websocket 訊息來自許多資料塊。對于所有其他服務器,當我使用 recv() 時,它會完全接收一個完整的 websocket 幀,但是這個特定的服務器將在 2 個 TCP 資料包中發送那個 websocket 幀,所以我必須再次使用 recv() 來獲取剩余的 websocket 幀。然后我嘗試用一??些 websocket 客戶端工具檢查這個服務器,它作業正常。我需要知道邏輯,為此實作 recv() 以及如何連接和計算何時完全接收到 websocket 幀以決議資料?請有人幫我解決這個問題。
while(1){
ws_recv_ret = recv(*ws_sock, ws_recv, 1024, 0);
ws_parser_execute(&ws_frame_parser1, ws_recv);
}
uj5u.com熱心網友回復:
TCP recv 可以接收任意數量的位元組,最多可以達到您要求的最大數量。“資料包”是完全不可預測的,您無論如何都不能依賴它們。
你如何判斷 websocket 框架的大小?當然,您使用 websocket 協議。websocket 標頭告訴您 websocket 幀中有多少位元組。您需要繼續呼叫 recv 直到獲得所有位元組。
如果您接收太多位元組,那么您需要保存額外的位元組并將它們用于下一幀。如果您仔細計算一次接收多少位元組,那么您將永遠不會接收太多,但是許多程式確實嘗試接收盡可能多的位元組,因為這樣效率更高,因此它們需要處理額外的位元組。
當然,因為“資料包”是完全不可預測的,所以“資料包”可能會在標題的中間結束。所以你需要不斷呼叫 recv 直到你有整個頭,然后你知道有多少位元組,然后你需要繼續呼叫 recv 直到你有所有的位元組。
更令人討厭的是,websocket 標頭可以有不同的大小。所以你需要一直呼叫 recv 直到你知道頭有多大,然后你需要繼續呼叫 recv 直到你有整個頭,然后你需要繼續呼叫 recv 直到你有所有的位元組。
uj5u.com熱心網友回復:
我在 recv 中使用了 MSG_DONTWAIT 標志并在回圈中運行它并將新資料附加到緩沖區。之后,recv 用 errno EAGAIN 拋出 -1 然后我打破回圈并決議 websocket 資料。并感謝@ user253751的解釋,它有助于消除我心中對實作的一些疑問。下面是我在我的庫中使用的代碼片段。
ws_recv_totalSize = 0;
ws_recv_ret = 0;
while(1){
ws_recv_totalSize = ws_recv_ret;
ws_recv_ret = recv(*ws_sock, ws_recv ws_recv_totalSize, MAX_BUFFER- ws_recv_totalSize, MSG_DONTWAIT);
if(ws_recv_ret <= 0)
break;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313425.html
