2012-03-08 132 views
0

我使用java.net包中,由於某種原因在客戶端和服務器之間的套接字關閉或者被損壞寫了一個對等網絡的網絡遊戲中的Java。我稱之爲「點對點」,因爲其中一個客戶端也運行一個服務器類,它只是一個我編寫的接受Socket連接的自定義類 - 一個來自另一臺計算機,另一臺來自客戶端計算機。 正在使用連接來使用ObjectOutputStream和ObjectInputStream來回移動對象。的ObjectOutputStream通過TCP套接字

插座錯誤不規則發生。出現問題前,連接通常會打開5-10分鐘。有時會在新遊戲開始時關閉,有時會在遊戲進行時關閉。

  1. 我應該使用keepAlive保持連接打開嗎?
  2. 沒有人對我應該如何去解決此問題有何建議?

這裏是代碼生成錯誤:

/** 
* Continually checks for messages to be read in. Then it 
* sends the messages to processMessage if a message is available. 
*/ 
    public void listenForMessages() { 
     int availableBytes; 
     Object obj = null; 
     try { 
     availableBytes = socketStream.available(); 
     if (availableBytes >5) { 
      obj = in.readObject(); 
      message = (ClientMessage) (obj); 
      processMessage(); 
     } 
     } 
     catch(java.io.StreamCorruptedException utoh) { 
      System.out.println("Read failed: " + utoh); 
      try { 
       System.out.println("Number of Bytes available: " + socketStream.available()); 
       utoh.printStackTrace(); 
       System.out.println("Attempting to close socked."); 
       socketStream.close(); 
      } 
      catch(IOException ioe) { 
       System.out.println("Unable to close: " + ioe.toString()); 
      }    
     } 
     catch(IOException e) { 
     System.out.println("Read failed" + e); 
     } 

以下是錯誤消息和堆棧跟蹤:

Read failed: java.io.StreamCorruptedException: invalid type code: 00 
Number of Bytes available: 100 

有兩個插座(兩個流)活性,每個客戶。當其他的插座拋出了同樣的錯誤,我看到無效類型代碼:FF

堆棧跟蹤

java.io.StreamCorruptedException: invalid type code: 00 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1355) 
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1946) 
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1870) 
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752) 
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328) 
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) 
at thornworks.quiz.PlayerInterface.listenForMessages(PlayerInterface.java:227) 
at thornworks.quiz.PlayerInterface.actionPerformed(PlayerInterface.java:214) 
at javax.swing.Timer.fireActionPerformed(Timer.java:291) 
at javax.swing.Timer$DoPostEvent.run(Timer.java:221) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641) 
at java.awt.EventQueue.access$000(EventQueue.java:84) 
at java.awt.EventQueue$1.run(EventQueue.java:602) 
at java.awt.EventQueue$1.run(EventQueue.java:600) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:611) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
+1

難以回答無碼問題。 – vulkanino 2012-03-08 15:51:37

+0

「套接字錯誤發生不規則」:*什麼*'套接字錯誤'?把它貼在這裏,用堆棧跟蹤。 – EJP 2012-03-09 00:15:38

+0

我發佈了一些代碼和堆棧跟蹤。希望有所幫助。 – Thorn 2012-03-09 15:48:31

回答

1

當創建網絡應用程序是非常重要的,以在年初推出的網絡I/O記錄發展。它將幫助您解決簡單的錯誤,如連接中斷和發送或接收的錯誤數據。

我假設你已經在測試環境中的連接問題:那就是本地網絡上? 你能描述你的客戶嗎?它是移動設備嗎?

如果應用程序需要連接不斷地開放,我會建議實施一些重新連接邏輯。即如果連接中斷(您在執行I/O操作時檢測到它),則嘗試與對等端重新建立連接。

UPDATE:

if (availableBytes >5) { 
    obj = in.readObject(); 
    message = (ClientMessage) (obj); 
    processMessage(); 
} 

是否有可用的字節序列化的幾個對象,會發生什麼? 什麼是in.readObject()?它是否爲對象序列化或可用的所有內容讀取所需的字節數量?

IMO你看到的行爲的原因可能是代碼不指望幾個對象可以同時接收並存儲在接收緩衝區。接收緩衝區也可以包含部分對象(例如object1 + object2的兩個字節)。

TCP是一個流協議,因此不能容易地確定消息結束。您應該實施協議,以確定正在傳輸的消息的開始和結束。 在您的代碼中

+0

我幾年前編寫了這個程序,當時我第一次學習Java,最近又剛剛學習了它。你的日誌建議非常好,現在我肯定會做,但不是10年前。測試環境是本地網絡,兩個客戶端都是運行Java 6的Windows PC。 – Thorn 2012-03-09 00:21:52