我正在使用基于事件的结构来处理游戏,并在服务器上托管主游戏逻辑;目前这是一个非常小的功能,只允许在两个参与者之间主持一场比赛。我读过关于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