2012-07-25 99 views
0

我是Java的新手,並通過UDP/TCP使用自己的網絡協議編寫程序。 C中有這樣的數據包:Java:如何描述一個網絡包?

struct test_package { 
    u32 cmd; 
    u32 args; 
    u32 flags; 
}; 

以UDP爲例,我從DatagramPacket得到的是字節數據[]。我怎樣才能將其轉換爲包結構?

如果在C中,如果沒有對齊限制,它只是(struct test_package *)data

感謝

+0

你需要知道,直接把C的結構到線工程是非常差的。它引入了編譯器,編譯器版本,周圍有效的#pragmas,編譯當天時使用的編譯器選項,......不推薦。你必須定義一個網絡字節協議,並且寫下任何你必須寫在你的編程語言中才能正確實現的協議。在正確地做這些事情時,Java所假設的低效率與C做錯時的明顯效率沒有可比性。 – EJP 2012-07-25 07:03:52

回答

0

Java沒有提供直接內存訪問,這樣你可以在你無法將其轉換爲結構C.你必須分析自己的字節數組,例如:

byte data[] = ...; 
DataInput input = new DataInputStream(new ByteArrayInputStream(data)); 

int cmd = input.readInt(); 
int args = input.readInt(); 
int flags = input.readInt(); 
+0

它看起來像我必須爲每種類型的包實現這樣的代碼。它看起來有點多餘,我必須這樣做。我不確定它是如何保持效率的,這樣的內存拷貝。 – 2012-07-25 03:23:12

+0

@ user1550330:是的,它有點多餘,但Java實際上是面向對象的代碼而不是像這樣的低級數據。如果你也關心效率,也許Java不是正確的解決方案。 – casablanca 2012-07-25 04:22:24

1

假設你有一個類:

public class TestPackage implements Serializable 
{ 
    long cmd; 
    long args; 
    long flags; 
} 

可以存儲在一個DatagramPacket類爲字節[]通過序列化它。然後在另一端,您可以將byte []並反序列化爲TestPackage的確切實例。

(這裏的序列化/反序列化可能是什麼樣子)

public static byte[] serialize(Object object) { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(out); 
    oos.writeObject(object); 
    return out.toByteArray(); 
} 

public static Object deserialize(byte[] datagramData) { 
    ByteArrayInputStream in = new ByteArrayInputStream(datagramData); 
    ObjectInputStream ois = new ObjectInputStream(in); 
    return ois.readObject(); 
} 
+1

這會工作,但它假定兩端都運行基於Java的客戶端。 – casablanca 2012-07-25 02:59:06

+0

它看起來像序列化/反序列化的通用方法。但它確保byte []數據佈局與struct test_package相同嗎? – 2012-07-25 03:13:16

+0

@ user1550330不,佈局不會一樣,就像卡薩布蘭卡說的那樣,它假定另一端也是Java,並且你正在傳遞*類*來回傳遞。 – 2012-07-25 03:15:59