簡體   English   中英

Java - 可通過套接字進行序列化和發送對象

[英]Java - serializable and sending object via socket

我收到一個錯誤:

IOException on socket listen: java.io.NotSerializableException: java.net.Socket

我嘗試使用以下代碼通過套接字發送對象:

ObjectOutputStream outObjects = new  ObjectOutputStream(socket.getOutputStream());
outObjects.writeObject(currentPlayer);

output.flush();

第二行給出錯誤....但我已經序列化(實現Serializable)類Player(currentPlayer對象的類)但Player類的成員之一是一個Socket對象.....我嘗試重新定義和序列化套接字對象但沒有辦法解決問題....我在哪里錯了?

您無法序列化Socket對象,因此您應該使套接字字段瞬態。 如果您需要某些套接字屬性,可以將額外的字段添加到Player以表示這些字段。

這意味着Socket類不可序列化。

您必須將Socket成員設置為瞬態,然后它將不會被序列化。

只需確保在私有readObject(ObjectInputStream)方法中重新創建Socket對象,否則您可能會遇到空指針異常。

編輯回答評論

嘗試將套接字成員聲明為transient

private transient Socket socket;

這將阻止序列化機器嘗試發送socket的值。 請注意,您無法有意義地將包含值(表示操作系統資源,如套接字句柄)的值的對象發送到另一個進程。 在最好的情況下,任何在接收方使用此類對象的嘗試都將導致拋出異常。 在最壞的情況下,這種嘗試可能會引入細微的錯誤(數據被發送給錯誤的用戶)。 出於這個原因,這些對象永遠不可序列化(除非有人犯了錯誤)。

請考慮以下(簡化)示例:在UNIX上,套接字由整數表示(所謂的文件描述符),在創建套接字時由OS返回。 如果將此值發送到另一個進程,則無法保證該數字實際上是指在接收進程中打開的有效文件句柄。 更糟糕的是,如果在接收過程中存在具有相同數值的文件句柄,則幾乎不可能在發送過程中引用相同的套接字打開。 因此,如果在發送數據時該數字實際上在接收過程中用作文件描述符,那么它幾乎肯定會在預定目的地之外的任何地方。

如果發送和接收進程在同一台機器上,則有一些方法可以將“套接字”從一個進程轉移到另一個進程。 但我懷疑,有一些簡單的方法可以從Java訪問這些OS調用。

implements Serializable本身並不能使對象可序列化。 對象本身中的任何和所有序列化字段必須依次可序列化(以及它們包含的任何和所有字段)。

由於套接字不可序列化,因此不應嘗試通過線路發送它。 您可以通過將其聲明為瞬態來將其排除在序列化之外。 然后,反序列化的對象當然沒有套接字,因此您可能還需要檢查對象中的可選readObject和writeObject方法,這些方法將用於序列化和反序列化。

查看有關序列化的這篇文章

套接字不可序列化,因為它與正在執行的機器,操作系統等相關聯。 要可序列化,對象的類必須實現Serializable,並且必須包含所有可序列化的遞歸對象。

因此,要序列化播放器,必須從序列化中排除其套接字屬性。 您可以通過聲明屬性瞬態來執行此操作:

private transient Socket mySocket;

當播放器被反序列化時,它的套接字將因此為空,並且它很可能無法正常工作。 您應該檢查一下您的設計,因為序列化需要套接字工作的對象可能沒有意義。

有幾種方法可以解決這個問題,最快的方法就是標記你的Socket成員transient 這可確保javas默認序列化將忽略Socket,並且您的副本應包含null。

private transient Socket sock;

或者,您可以提供自己的序列化方法,這要求您自己編寫和閱讀所有成員。 您可以使用Serializable中定義的方法(參見下文)或實現Externalizable

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;

最干凈的是將您的玩家狀態與您的網絡代碼分開,從而產生僅具有Seri​​alizable成員的類。 作為獎勵,發送類不再包含無效的成員字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM