2013-08-29 208 views
0

因此,在過去的幾周裏,我一直在學習非常簡單的網絡編程和協議緩衝區。現在,我有一個Java客戶端和一個使用協議緩衝區來回傳輸的C#服務器。這一切工作正常,但爲了使它在客戶端(Java)端工作,我必須創建具有傳入消息的確切大小的字節數組,否則解析器會拋出「協議消息包含無效標記(零)「Java協議緩衝區 - 消息大小

經過一番研究,我發現我爲DatagramPacket創建的數組(1024bytes)有大量的尾隨零(因爲我從服務器接收到的數據長度是27bytes),這就是爲什麼我現在,如前所述,必須創建具有確切大小的傳入數據的陣列。

至於這個問題,有沒有什麼方法可以找到我的.proto文件中的所有「proto」消息的大小?如果沒有某種靜態的getSize(),有沒有一種方法可以根據「消息」中的字段類型來計算?

我現在使用的信息包含3個雙打,現在我正在考慮這個問題,但是我想知道發生了什麼的人肯定會回答,是因爲每個雙8bytes,每個消息字段上每個「標籤」1個字節?

+0

您可以發送發送協議緩衝區消息之前的長度。 –

回答

0

protobuf數據中的根對象不是自行終止的;它被設計成可追加的(追加===合併),所以通常庫會直接讀取,直到數據用完。如果您有零備份,它將無法解析下一個字段標題。有兩種解決方法:

  • 如果您只想發送一條消息,只需在消息末尾關閉出站套接字;客戶端應該檢測到套接字的末端並進行相應的補償(注意,除非使用長度限制的流封裝,否則您仍然不想使用超大緩衝區)
  • 使用某種「成幀」協議;最簡單的方法是簡單地在每個消息前面加上該消息中的字節數(注意在一般情況下,這個大小不是固定的,但是在3個雙打的情況下,每個都有一個字段頭的字段號不大於16,則是:它將是27個字節);然後您可以創建正確大小的緩衝區(注意重複的數組分配可能很昂貴),或者更典型的是:使用長度受限的流封裝或內存支持的內存流
0

我相信你的問題在於你的套接字接收代碼。有一個尾隨零的數組不是問題,但是當收到你應該檢查接收到的字節數(它是一個接收調用的返回值),並且只考慮緩衝區數組的字節從開始到「收到的字節數」。