2012-04-05 36 views
0

我正在使用基於事件的結構來處理遊戲,並在服務器上託管主遊戲邏輯;目前這是一個非常小的功能,只允許在兩個參與者之間主持一場比賽。我讀過關於ServerSocket的各種問題,他們都沒有回答我的問題。我已經看了看SeverSocket停止接受

在項目中,我利用ObjectInputStreamObjectOutputStream。一切按預期工作(在服務器端和客戶端都接收/發送),但是在兩個套接字都註冊之後,即使之前調用相同的代碼,實例中的accept方法也會一直阻塞。也許這是通過套接字進行一次通信後出現的問題?

我的服務器日誌顯示以下:

等待接受
接受第一插座
發送事件到SOCKET1用於通知等待對手
等待接受
接受第二插座
發送迴應給兩個插座
等待接受(並永遠阻止)

當日志顯示發送的響應事件時,它們在客戶端正確接收和處理。客戶端調試輸出顯示,下一個事件是,肯定是發送的。也許這是關於不關閉客戶端套接字(在第三個鏈接問題中提到)?無論如何,我無法關閉客戶端套接字,因爲進一步的溝通是不可能的。

客戶端代碼

public void send(Event e) { 
    try { 
     ObjectOutputStream out = new ObjectOutputStream(
       socket.getOutputStream()); 
     out.writeObject(e); 
     out.flush(); 
     log.debug("sending event... "+e); 
    } 
    catch(IOException ioe) { 
     log.fatal("constructing oos failed", ioe); 
    } 
} 

服務器端代碼

@Override 
public void run() { 
    running = true; 
    while(running) { 
     try { 
      Socket s = socket.accept(); 
      ObjectInputStream ois = new ObjectInputStream(s.getInputStream()); 
      Event event = (Event) ois.readObject(); 

      try { 
       Event[] response = controller.consume(event); 
       ObjectOutputStream oos = new ObjectOutputStream(sockets[0].getOutputStream()); 
       oos.writeObject(response[0]); 
       oos.flush(); 
       ObjectOutputStream oos2 = new ObjectOutputStream(sockets[1].getOutputStream()); 
       oos2.writeObject(response[1]); 
       oos2.flush(); 
      } 
      catch(...) { 
       // multiple catch clauses for different exceptions 
       // all just logging (nothing passes silently!) 
      } 
    } 
} 

爲了縮短,對於兩個插座分配給Socket[]陣列方法被排除,但由於存在沒有例外,保持套接字工作。你有什麼想法可能導致描述的行爲?先謝謝你。

+0

我建議你閱讀[網絡教程](http://docs.oracle.com/javase/tutorial/networking/index.html)。尤其是[socket部分](http://docs.oracle.com/javase/tutorial/networking/sockets/index.html)。 – Jeffrey 2012-04-05 22:29:58

+0

我已經閱讀了教程。它不包括對象流,並且在處理多個客戶端上的四行僞代碼是不夠的。 – phineas 2012-04-05 22:38:19

回答

1

accept方法只接受新的連接。由於您只有兩個客戶端嘗試連接到您的服務器,因此您將在第三次調用accept時無限期地掛起。

備註:您不需要持續創建新的ObjectInputStream s和ObjectOutputStream s。您可以爲每個Socket創建一個,並保留對它們的引用以供重用。

+0

好的提示。所以結構方面必須改變。處理這兩種行爲,註冊新連接和維護現有連接的方法是什麼? – phineas 2012-04-05 23:00:38

+0

多線程,或使用[非阻塞IO](http://www.ibm.com/developerworks/java/library/j-javaio/)。 – Jeffrey 2012-04-05 23:08:03

相關問題