我正在使用基於事件的結構來處理遊戲,並在服務器上託管主遊戲邏輯;目前這是一個非常小的功能,只允許在兩個參與者之間主持一場比賽。我讀過關於ServerSocket
的各種問題,他們都沒有回答我的問題。我已經看了看SeverSocket停止接受
- ServerSocket accept continues to block
- ServerSocket.accept()
- Java ServerSocket won't accept new connections until close() is called on the accepted socket
- ServerSocket accept() method
在項目中,我利用ObjectInputStream
和ObjectOutputStream
。一切按預期工作(在服務器端和客戶端都接收/發送),但是在兩個套接字都註冊之後,即使之前調用相同的代碼,實例中的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[]
陣列方法被排除,但由於存在沒有例外,保持套接字工作。你有什麼想法可能導致描述的行爲?先謝謝你。
我建議你閱讀[網絡教程](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
我已經閱讀了教程。它不包括對象流,並且在處理多個客戶端上的四行僞代碼是不夠的。 – phineas 2012-04-05 22:38:19