1 回答

TA貢獻2036條經驗 獲得超8個贊
我認為你的問題非常標準:不注意TCP不實現消息邊界的事實,只是通過連接傳輸兩個不透明的字節流。
這意味著,當您將一串字節“Hello world從客戶端”發送到連接的套接字(已建立的TCP連接)時,連接的另一端不知道客戶端的消息在哪里結束,除非客戶端以某種方式傳達它本身;根本沒有辦法使用TCP本身來劃分單個消息。
輸入“應用程序級協議”:除非您打算使用TCP的數據交換任務自然地傳輸單個“消息” - 想象一下服務器將單個文件的內容轉儲到每個連接的客戶端并關閉連接 - 您必須發明一些方法讓客戶端告訴服務器它發送的每條消息實際上在哪里結束。
考慮一下您的示例:在讀取過程中,您基本上有一個循環,該循環從套接字重復讀取數據塊,具有單個退出條件:到達該套接字上的文件末尾。只有當遠程端(在本例中為客戶端)關閉其連接端時,才會報告 EOF,而客戶端從不這樣做:它發送一個字符串,然后等待服務器發回一些東西,但服務器從不回復,因為它永遠不會完成讀取。
有多種方法可以解決問題。
發明一個自定義協議(例如,在TLV系列中),它將實現消息成幀。
例如,在最簡單的形式中,該協議可以定義為單個無符號字節,其中包含以下消息的長度(以字節為單位)。
然后,服務器將有一個兩步過程來讀取客戶端的每條消息:讀取單個字節;
如果成功,請讀取由前導字節值定義的任意數量的后續字節;
成功后,請返回步驟 1 以閱讀以下消息。
想出一個消息分隔符,如ASCII LF字符 - 可以編碼為Go的字符串文本,并使服務器繼續讀取,直到遇到LF;一旦它發現了一個LF,它就知道它應該處理消息,然后開始讀取另一個消息。
\n
圍棋有方便的類型
布菲奧。讀取器
在其標準包中,可以從由LF分隔的任何單個行中讀取。io.Reader
具有更復雜的消息框架,例如使用 JSON 流發送 JSON 文檔。
由庫存包實現的解碼器的一個經常監督的功能是,它可以解碼JSON對象的流,以此為例。
encoding/json
可能性實際上很多,所以我只是觸及了表面,我認為你應該明白這個想法。
- 1 回答
- 0 關注
- 108 瀏覽
添加回答
舉報