0

我制作了一个通过 ObjectInputStream 从服务器接收数据的信使。我希望能够检索/发送可序列化文件,同时还能够从用户那里检索/发送消息。

我找不到一种在两者(对象和消息)之间进行排序而不引起消息冲突的好方法。

我尝试为同一个套接字使用两个流(Data*Stream 和 Object*Stream),它似乎建立得很好,但是当我尝试通过 Data*Stream 从服务器向客户端发送消息时,我开始java.net.SocketException: socket closed使用我的客户。(仅在我发送消息时发生)

有人可以指出我将如何通过流检索两种不同类型的信息的正确方向吗?(没有采取简单的出路。我不想这样做writeObject("[message]"+input);或任何像这样的廉价技巧。



(编辑)解决方案:

感谢 janos,他启发了我编写这段代码。:') 谢啦

输入接收器:

protected Object data;

public synchronized Object receivedData() throws ClassNotFoundException,
                                                 IOException {
    data = in.readObject();

    if(!(data instanceof String)) {
        retrieveObject();
        data = "";
        System.out.println("Object");
    }
    return data;
}

和消息传递线程:

ExecutorService pool = Executors.newScheduledThreadPool(1);

private Runnable receiveData;
public void receiveData() {
    receiveData = new Runnable() {

        public void run() {
            String input;
            try {
                while((input = (String) receivedData()) != null) {
                    if(input.length() > 1) 
                        System.out.println(input);

                }
            }catch(IOException | ClassNotFoundException e){ e.printStackTrace();}
        }
    };

    pool.execute(receiveData);
}

如果您有任何改进提示,请告诉我,我会更新此代码。

4

2 回答 2

1

您可以创建父类Message、子类DataMessageTextMessage.

收到 aMessage时,您可以检查instanceof其基础类型,并进行相应处理。

这些*Message类可以将您想要在客户端和服务器之间传递的任何对象包装在它们的成员变量中。类*Message必须是可序列化的,因此所有成员变量也必须是可序列化的。

例如给定这些Message类型:

class Message {}

class TextMessage extends Message {
    String text;
}

class DataMessage extends Message {
    User user;
}

您可以处理收到的消息,例如:

Message message = (Message) in.readObject();
if (message instanceof TextMessage) {
    // do something with ((TextMessage)message).text
} else if (message instanceof DataMessage) {
    // do something with ((DataMessage)message).user
}
于 2013-10-20T09:07:04.130 回答
1

我希望能够检索/发送可序列化文件,同时还能够从用户那里检索/发送消息。

您可以使用ObjectInputStreamand完成所有这些操作ObjectOutputStream

我找不到一种在两者(对象和消息)之间进行排序而不引起消息冲突的好方法。

在您指定“冲突”之前,该声明是没有意义的。

我试过为同一个套接字使用两个流(Data*Stream & Object*Stream)

  1. 你不能那样做。在套接字的整个生命周期中使用相同的流。

  2. 你不需要这样做。你可以用 a 做的任何事情都Data*Stream可以用 an 做,Object*Stream,因为Data*StreamimplementsData*PutObject*StreamimplementsObject*Put以及Object*Putextends Data*Put

它似乎建立得很好,但是当我尝试通过 Data*Stream 从服务器向客户端发送消息时,我得到 java.net.SocketException: socket closed on my client。

这意味着关闭了流并继续使用它。这是由于您使用了两个流造成的。关闭任何包裹在套接字输入或输出流周围的流会关闭另一个流和套接字。你不需要这个。

(仅在我发送消息时发生)

仅当您读取或写入已关闭的流时才会发生这种情况。

有人可以指出我将如何通过流检索两种不同类型的信息的正确方向吗?

只需使用Object*Stream.

(没有采取简单的方法。我不想做 writeObject("[message]"+input); 或任何类似的廉价技巧。

我不知道你为什么认为这是一个“便宜的把戏”。您需要停止做出假设并开始设计。

于 2013-10-20T09:14:03.090 回答