我正在构建一个聊天程序,其中主机通过套接字连接,并使用ObjectInput和ObjectOutput流彼此对话。主机通过键盘输入构建字符串,并将其与整数数组一起发送给其他主机。
主机成功通过readObject()读取消息后,while(true)循环继续,并且该主机挂在下一次readObject()调用上。我只能推测这是因为indata.available()即使读取了其中的内容也返回了true,并且当它尝试在发送其他内容之前再次读取时,它会阻塞(等待)。
下面是相关代码的片段。我进行了一些研究,发现无法刷新或清空输入流。我也无法关闭它-由于不断运行的聊天程序的性质,它需要保持打开状态才能继续阅读。
此外,我了解我正在检查indata.available(),然后使用inputs.readObject()进行读取。我以为这是正确的做法,但是如果我错了,请纠正我。
我不确定该怎么办!如果尚未向流中写入对象,则需要indata.available()返回0。
private InputStream[] indata;
private ObjectInputStream[] inputs;
private ObjectOutputStream[] outputs;
private int[] stamps;
// Establish connections via sockets between 3 hosts, serverless
while (true) {
// Build a message
for (all hosts that aren't myself) {
if ( i != rank ) {
outputs[i].writeObject( message );
outputs[i].writeObject( stamps );
outputs[i].flush( );
outputs[i].reset( );
}
}
// Read a message in from a host that sent one
for (all hosts that aren't myself) {
if (indata[j].available() > 0) {
String message = (String)inputs[j].readObject();
int[] senderStamps = (int[])inputs[j].readObject();
}
}
}
一些其他信息,以供澄清:
我使用的是available(),因为讲师在其代码中使用了它,并且不允许我对其进行更改。此外,当仅发送一个对象(字符串)时,对available()的调用将按预期的方式工作-发送方唯一的代码是“ writeObject”和“ flush”。添加代码以发送数组是我的工作,当我这样做时,我还必须添加代码以reset()ObjectOutputStream(否则我会遇到其他问题-在发送,修改并发送数组时再次在发送之间不调用reset()的情况下,将发送未修改的原始版本,而不是新修改的版本。
我不能只是在读取时阻塞,因为在读取时阻塞的进程无法写入其他主机,因此即使主机没有任何内容,我也必须能够写入。
此外,我们不允许使用多个线程。
答案 0 :(得分:0)
我知道发生了什么,但是我不确定为什么。
当我在发送后调用reset(),然后在接收端读取对象时,流中还剩下1个字节。这就是导致我陷入if子句中,然后在再次读取时阻塞的原因(因为实际上没有要读取的对象)。
我必须调用reset,因为我正在发送一个持久对象(数组)。我注意到当我只发送字符串时,我不必调用reset,而字符串和数组之间的区别在于,每次循环时都重新创建字符串时,数组是该类的数据成员。跑了。
因此,我创建了要发送的阵列的非持久副本,并发送了该副本。当我这样做时,我不必打电话给reset(仍然不明白为什么)。此外,从输入流读取后,内部还剩下0个字节,因此它永远不会将程序置于readObject会阻塞的位置。
我想我有点理解为什么发送非持久对象时不必重置,但是我不明白为什么reset()导致数据保留在相应的输入流中。
无论哪种方式,它现在都可以正常工作。