具有多个客户端的Java SocketServer - StreamCorruptException

时间:2011-06-24 20:02:56

标签: java sockets serversocket objectoutputstream objectinputstream

应用程序

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

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

此处server变量是此节点侦听的套接字,client变量是其他节点侦听的套接字,以及此节点向其发送对象。

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

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)的实例和一些异常,例如。)

我的直觉告诉我,不知何故,两个对象/字节流混合在一起,这在尝试反序列化对象时会产生奇怪的结果。我的问题是:为什么会发生这种情况,又说我做错了什么,我怎么能解决它?

2 个答案:

答案 0 :(得分:1)

您有一组套接字,但您似乎没有一组编写器和读者。因此,您可能正在使用相同的编写器和读取器进行所有连接。

实际上你应该有一个每连接的Connection对象,它实现了Runnable,并且有Socket,writer和reader作为实例成员。

当你捕获EOFException时,你必须突破循环并关闭writer。

答案 1 :(得分:0)

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