2012-08-13 65 views
2

我有另一個套接字問題。與其他問題相比,這實際上很奇怪。好吧,我有一個客戶端連接到服務器,通過ObjectOutputStream以恆定速率發送數據,並通過ObjectInputStream接收數據。我有一個充滿玩家對象的列表,其中包含玩家座標,遊戲模式等。當客戶端移動其玩家時,更新後的座標被髮送到服務器,並且列表中該玩家的對象被更新。那麼,應該更新...我打印出服務器端的變化的座標,但是當我發送列表給玩家打印出來時,座標沒有改變。這裏是玩家等級:Java:List沒有正確地通過套接字發送?

public static class Player implements Serializable { 
    private static final long serialVersionUID = 8841477887428285969L; 
    public int x, y, gamemode, ID; 
    public String name; 
    public Player(int x, int y, int gamemode, int ID, String name) { 
     this.x = x; 
     this.y = y; 
     this.gamemode = gamemode; 
     this.ID = ID; 
     this.name = name; 
    } 

    public void setPosition(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 
} 

如果服務器臨危更新座標和之前和之後進行打印:

Package.Client_Server main_packet = (Package.Client_Server) obj; 
System.out.println(S00.getPlayerByID(ID).x + ", " + S00.getPlayerByID(ID).y); 
S00.getPlayerByID(ID).setPosition(main_packet.x, main_packet.y); 
System.out.println(S00.getPlayerByID(ID).x + ", " + S00.getPlayerByID(ID).y); 

而且這裏是從服務器發送客戶端打印出自己的座標。 問題在這裏...更新的座標不顯示在這裏,但仍舊是舊座標。難道我做錯了什麼?列表中仍然只中有一個對象,因此它不只是創造更多的對象某處...

Package.Server_Client main_packet = (Package.Server_Client) obj; 
ID = main_packet.client_ID; 
C00.players = main_packet.players; 
System.out.println(C00.players.get(ID).x + ", " + C00.players.get(ID).y); 
System.out.println(main_packet.players.get(ID).x + ", " + main_packet.players.get(ID).y); 
//I tried printing the list directly from the package as well but it isn't updated either... 

哎呀,我還要告訴從服務器發送到列表中持有的客戶端軟件包在:

public static class Server_Client implements Serializable { 
    private static final long serialVersionUID = 5198487406288606819L; 
    public int client_ID; 
    public int online; 
    public List<Player> players; 
    public Server_Client(int client_ID, int online, List<Player> players) { 
     this.client_ID = client_ID; 
     this.online = online; 
     this.players = players; 
    } 
} 

我的整個問題是,更新後的座標是玩家在服務器端列表中,但一旦列表發送到客戶端,更新後的數據不再更新......這是整個過程開始之前也是如此。這是套接字如何工作的問題,還是我可怕地陷入了一個小錯誤? List不能成爲問題,因爲我將它交換爲一個Player對象數組,但它仍然不會在客戶端正確讀取。幫幫我?

編輯:也可以看到這種效果,因爲當另一個客戶端連接到服務器時,客戶端1無法看到客戶端2,因爲該列表未更新,但客戶端2可以看到客戶端1,因爲他當他第一次連接到服務器時。客戶端1的控制檯總是說他是唯一連接的玩家(列表中有1項),而控制檯2總是說有2個玩家連接(即使客戶端1已斷開連接)。因此,該列表未被更新。那麼可能會導致這種情況?

這裏是法「getPlayerByID(INT ID)」:

public static Package.Player getPlayerByID(int ID) { 
    for(int i = 0; i < players.size(); i++) { 
     if(players.get(i).ID == ID) { 
      return players.get(i); 
     } 
    } 
    throw new NoSuchElementException("No player has the ID: " + ID); 
} 
+0

你能展示更多代碼嗎? – oldrinb 2012-08-13 21:16:44

+0

你想要什麼樣的代碼?我有很多東西可以展示(雖然這幾乎是我所有與這個問題有關的代碼...) – CoderTheTyler 2012-08-13 21:17:17

回答

7

確保如果傳遞相同的對象引用的ObjectOutputStream單個實例repeatatly您正在使用ObjectOutputStream.writeUnshared(Object)做OR在該對象的寫入之間調用ObjectOutputStream.reset()

如果您未能做到這一點,ObjectOutputStream將看到已寫入的對象,並寫入對先前序列化形式的引用,而不是第一次寫入對象時的序列化狀態。

+0

好的抱歉,如果我在這裏聽起來無知或沒有受過教育,但是...什麼?這聽起來像是什麼可能導致這個問題,考慮到它總是會以某種方式發送相同的列表,但是如何實現修復? (對不起,我是編碼方面的新手)每次發送對象時,是否只是在輸出流上調用.reset()? – CoderTheTyler 2012-08-13 21:27:43

+0

哦,等一下!我知道了!重置()做了訣竅。太感謝了!另外,調用reset()是否會影響除此之外的其他任何內容?只是想知道如果我注意到後面fritz上的其他內容有所改動 – CoderTheTyler 2012-08-13 21:29:34

+0

或者,您可以使用'writeUnshared(Object)'而不是'writeObject(Object)'來實現相同的結果。 – Dev 2012-08-13 21:30:23