2012-04-05 65 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