【问题标题】:SeverSocket stops acceptingSeverSocket 停止接受
【发布时间】:2012-04-05 22:21:05
【问题描述】:

我正在开发一款基于事件结构的游戏,其主要游戏逻辑托管在服务器上;目前它是一个非常小的功能集,只允许在两个参与者之间举办一场比赛。我已经阅读了有关ServerSocket 的各种问题,但没有一个回答我的问题。我已经看过了

在我的项目中,我使用ObjectInputStreamObjectOutputStream。一切都按预期工作(在服务器和客户端都接收/发送),但是在注册两个套接字之后,ServerSocket 实例的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[] 数组的方法被省略了,但是由于没有没有例外,因此保持套接字有效。您知道什么可能导致所描述的行为吗?提前谢谢你。

【问题讨论】:

  • 我建议你阅读Networking tutorial。尤其是socket section
  • 我已经阅读了教程。它没有涵盖对象流,处理多个客户端的四行伪代码还不够。

标签: java sockets networking


【解决方案1】:

accept 方法只接受 new 连接。由于您只有两个客户端尝试连接到您的服务器,因此它将在您第三次调用 accept 时无限期挂起。

旁注:您不需要不断创建新的ObjectInputStreams 和ObjectOutputStreams。您可以为每个Socket 创建一个并保留对它们的引用以供重复使用。

【讨论】:

  • 好提示。所以结构方面必须改变。处理这两种行为、注册新连接和维护现有连接的方法是什么?
  • 多线程,或者使用non-blocking IO
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 2014-03-07
  • 2016-02-08
  • 1970-01-01
  • 2019-04-30
相关资源
最近更新 更多