TCP是一個串流的協議,客戶端傳送一段資料到伺服器到伺服器後,可能不會被伺服器一次就完整的接收。客戶端向伺服器發送多段數據,可能伺服器一次就接收到了全部。 (建議學習: swoole視訊教學)
在實際應用中,希望在伺服器上能夠一次接收完整的數據,且不多也不少。
傳統的TCP伺服器中,往往需要由程式設計師維護一個快取區,先將讀取到資料寫入快取區,然後再透過預先設定好的協定內容來區分一段完整資料的開頭、結尾和長度,並將一段完整的資料交給邏輯部分處理,這就是自訂協定的功能。
在Swoole中已經在底層實現了一個資料快取區,並內建了幾種常用的協定類型,並直接在底層做好了資料的拆分,以保證在onReceive回調函數中,一定能夠收到一個或數個完整的資料段。
資料快取區的大小可以透過配置pakcage_max_length來控制。
$configs = []; $configs["package_max_length"] = 8192; $server->set($configs);
swoole目前支援兩種通訊協定:EOF結束符協定、固定包頭加包體協定
package_max_length
package_max_length用於設定最大資料包尺寸,當開啟open_length_check或open_eof_check或open_http_protocol等協定解析後,Swoole底層會進程資料包拼接,此時在資料包未收取完整時,所有資料都會儲存在記憶體中。
所以需要設定package_max_length一個封包最大允許佔用的記憶體尺寸。
如果同時有1萬個TCP連接在發送數據,每個數據包2MB,在最極端的情況下會佔用20GB的記憶體空間。所以此參數不宜設定過大,否則會佔用很大的記憶體。
相關配置選項
open_length_check
當發現資料包長度超過package_max_length時會直接丟棄此資料並關閉連接,因此不會佔用任何內存,適用於websocket、 mqtt、http2協定。
open_eof_check
由於無法事先得知資料包的長度,所以接收到的資料還是會保存在記憶體中持續成長。當發現記憶體佔用已經超過package_max_length時,將直接丟地此資料包並關閉連線。
open_http_protocol
HTTP的GET請求最大允許8KB資料且無法修改此配置,POST請求會偵測Content-Type,如果發現超過package_max_length則直接丟地此數據,並發送HTTP 400錯誤並關閉連線。
EOF協定
使用一組固定的、不會在正常資料內出現的字串/r/n作為分割協定的標記,稱之為EOF協定.
什麼是EOF協定呢?
EOF全名為 End of File,使用\r\n作為結束標記。
在逐一讀取資料流中的資料時,如果發現讀到EOF標記,就表示已經讀到資料末端。
在TCP的資料流中,使用EOF協定的資料流的特徵是|資料|EOF|資料|EOF|。
EOF協定處理的原理是在每串正常資料的末尾會添加一個預先規定的且絕對不會再資料中出現的字串作為結束標記,這樣接收到的資料就可以根據EOF標記來切分數據。
典型的memcached、ftp、stmp都是使用/r/n作為結束符。當發送資料時只要在資料包的末尾添加/r/n即可。
使用EOF協定處理一定要確保資料包中間不會出現EOF,否則將會造成分包錯誤。
以上是swoole用什麼協議的詳細內容。更多資訊請關注PHP中文網其他相關文章!