我是Java的新手,並通過UDP/TCP使用自己的網絡協議編寫程序。 C中有這樣的數據包:Java:如何描述一個網絡包?
struct test_package {
u32 cmd;
u32 args;
u32 flags;
};
以UDP爲例,我從DatagramPacket得到的是字節數據[]。我怎樣才能將其轉換爲包結構?
如果在C中,如果沒有對齊限制,它只是(struct test_package *)data
。
感謝
我是Java的新手,並通過UDP/TCP使用自己的網絡協議編寫程序。 C中有這樣的數據包:Java:如何描述一個網絡包?
struct test_package {
u32 cmd;
u32 args;
u32 flags;
};
以UDP爲例,我從DatagramPacket得到的是字節數據[]。我怎樣才能將其轉換爲包結構?
如果在C中,如果沒有對齊限制,它只是(struct test_package *)data
。
感謝
Java沒有提供直接內存訪問,這樣你可以在你無法將其轉換爲結構C.你必須分析自己的字節數組,例如:
byte data[] = ...;
DataInput input = new DataInputStream(new ByteArrayInputStream(data));
int cmd = input.readInt();
int args = input.readInt();
int flags = input.readInt();
它看起來像我必須爲每種類型的包實現這樣的代碼。它看起來有點多餘,我必須這樣做。我不確定它是如何保持效率的,這樣的內存拷貝。 – 2012-07-25 03:23:12
@ user1550330:是的,它有點多餘,但Java實際上是面向對象的代碼而不是像這樣的低級數據。如果你也關心效率,也許Java不是正確的解決方案。 – casablanca 2012-07-25 04:22:24
假設你有一個類:
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();
}
這會工作,但它假定兩端都運行基於Java的客戶端。 – casablanca 2012-07-25 02:59:06
它看起來像序列化/反序列化的通用方法。但它確保byte []數據佈局與struct test_package相同嗎? – 2012-07-25 03:13:16
@ user1550330不,佈局不會一樣,就像卡薩布蘭卡說的那樣,它假定另一端也是Java,並且你正在傳遞*類*來回傳遞。 – 2012-07-25 03:15:59
你需要知道,直接把C的結構到線工程是非常差的。它引入了編譯器,編譯器版本,周圍有效的#pragmas,編譯當天時使用的編譯器選項,......不推薦。你必須定義一個網絡字節協議,並且寫下任何你必須寫在你的編程語言中才能正確實現的協議。在正確地做這些事情時,Java所假設的低效率與C做錯時的明顯效率沒有可比性。 – EJP 2012-07-25 07:03:52