【问题标题】:Java SocketServer with multiple clients - StreamCorruptException具有多个客户端的 Java Socket 服务器 - StreamCorruptException
【发布时间】:2011-09-22 07:47:21
【问题描述】:

应用程序

我正在用 Java 编写一个客户端/服务器应用程序,它通过使用 ObjectStream 类通过套接字发送对象来进行通信。应用程序中的每个节点大致如下所示:

class Node {
  SocketServer server;
  Socket[] clients;
}

这里server变量是这个节点监听的socket,client变量是其他节点监听的socket,这个节点发送对象的socket。

我用来将对象写入其中一个客户端套接字的代码如下所示:

void sendMessage(Message<B, F> msg) throws IOException {
    ObjectOutputStream writer = getWriter();
    writer.writeObject(msg);
    writer.flush();
}

private ObjectOutputStream writer;

ObjectOutputStream getWriter() throws IOException {
    if (writer == null)
        writer = new ObjectOutputStream(
            new BufferedOutputStream(client.getOutputStream()));
    return writer;
}

我用来处理连接和从节点的服务器套接字读取对象的代码如下所示:

// the handler will listen for connections
final Thread handler = new Thread(new Runnable() {

    public void run() {
        try {
            // create a new thread to handle the client
            final Socket client = server.accept();
            final Thread thread = new Thread(new Runnable() {

                public void run() {
                    final ObjectInputStream reader;
                    try {
                        reader = new ObjectInputStream(client.getInputStream());
                        while (true) {
                            try {
                                val msg = reader.readObject();
                                messages.add((Message<B, F>) msg);
                            }
                            catch (EOFException e) {
                                // i noted it seemed to throw eofexceptions
                            }
                            catch (IOException e) {
                                // do something
                            }
                        }
                    }
                    catch (IOException e) {
                        // do something
                    }
                }
            });
          thread.start();
        } catch (IOException e) {
            // do something
        }
    }
});
handler.start();

问题

我认为我在这里的套接字做错了什么。当每台服务器只连接到一个客户端时,一切正常。但是,当多个客户端与同一个服务器通信时,事情变得很糟糕,我从 ObjectInputStream 和其他奇怪的行为中得到了 StreamCorruptedException(放入一个 UpdateRequest 消息的实例,并取出一个 Integer(0) 的实例和一些异常,例如。)

我的直觉告诉我,这两个对象/字节流以某种方式混合在一起,这在尝试反序列化对象时会产生奇怪的结果。我的问题是:为什么会发生这种情况,也就是我做错了什么,我该如何解决?

【问题讨论】:

  • 什么时候关闭阅读器?
  • 对我来说似乎是一个可能的同步问题。是否有多个线程可以写入 ObjectOutputStream?另外,尽量不要称它为writer。 Writer 意味着文本而不是二进制数据。
  • @Amir Oooh,更重要的是,你如何关闭作者?
  • 我已经有一段时间没有做过类似的 Java 网络了,但我记得当我第一次学习它时,Java Socket 教程对我帮助很大。也许它对你也是一个很好的参考。 oracle.com/technetwork/java/socket-140484.html#multi
  • 嗯...我不关闭输出流,因为这会给我一个异常说套接字已关闭。这会导致什么样的错误,为什么?

标签: java sockets serversocket objectoutputstream objectinputstream


【解决方案1】:

你有一个 Sockets 数组,但你似乎没有一个 writer 和 reader 数组。因此,您可能对所有连接使用相同的写入器和读取器。

确实,您应该有一个每个连接的 Connection 对象,它实现了 Runnable,并且将 Socket、写入器和读取器作为实例成员。

此外,当您捕获 EOFException 时,您必须跳出循环并关闭编写器。

【讨论】:

  • 您对我的解释提出了一个很好的观点 - 我有一个具有 sendMessagegetWriter PER 客户端套接字的类的实现,所以这不是问题。
  • 此外,您能否详细解释一下 EOFException 和中断/关闭?
  • @Pepijn 对我来说似乎很清楚。当你得到一个 EOFException 时,没有什么要读的了,所以你必须停止阅读,关闭文件,退出读取循环,...
【解决方案2】:

问题是由于同时发送消息而发生的,这导致字节混合。解决方案是确保一次只接收一条消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多