我正在尝试创建一个在互联网上运行的多人游戏。问题是,我试图在一个流上获得输入,由于某种原因,我无法用一个套接字生成两个流,我将解释:
Socket s=new Socket("127.0.0.1",5001);
ObjectInputStream obj1=new ObjectInputStream(s.getInputStream());
ObjectInputStream obj2=new ObjectInputStream(s.getInputStream());
有人能解释一下为什么这个代码片段不起作用吗?
编辑:这是另一个不起作用的代码示例。
while (true) {
try {
objI = new ObjectInputStream(sock.getInputStream());
objO = new ObjectOutputStream(sock.getOutputStream());
}catch(Exception e) {
e.printStackTrace();
}
}
编辑2:非常感谢你的回答。我试图刷新对象,但我一直得到这个错误:
java.io.StreamCorruptedException: invalid stream header: 33740003
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at Proccess.run(Proccess.java:22)
at java.lang.Thread.run(Unknown Source)
流是有状态的-当您从流中读取时,您正在从流中的某个位置读取,通过这样做可以更改位置。
如果同时从底层流读取两个东西(比如两个包装器ObjectInputStreams),它们都会尝试更改流中的位置,但都不知道对方在做什么。因此,从一个流中读取会改变位置,然后另一个流会期望流在它离开的位置,但事实并非如此。
想象一下,你得到的答案是写在不同纸张上的单词,一个接一个地给你。但是,当你阅读这些纸片时,别人在你还没看到它们之前就把它们拿走了——你得到的是没有意义的。这就是正在发生的事情——一个流拿走了部分数据,当另一个流再次查看数据时,其中一些数据丢失了,被另一个数据流消耗掉了。
拥有一个ObjectInputStream,用于读取传入对象。如果您想将这些对象发布给多个使用者,请创建一个要将传入对象发送到的对象集合,然后对它们进行迭代,并将新对象传递给每个使用者。
Socket是一个全双工管道。它有一个输入流和一个输出流。要拥有多个流,您应该在其上构建一个多路复用协议(TCP)。
在不知道错误消息的情况下,代码应该发生的情况是,您总是获得相同的输入/输出流,并且在尝试获取ObjectInputStream
时应该挂起。这是由于这样一个事实,即由于某种原因,新创建的ObjectInputStream
需要与相应的ObjectOutputStream
通话并等待其连接。我总是使用以下代码:
Socket socket = new Socket("localhost", 12345);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
通过对flush
的调用,套接字另一侧的输入流是愉快的并继续。
EDIT,关于您的Edit2:这看起来像是第二个ObjectOutputStreams向第一个InputStream读取的流写入一些元数据(反之亦然)。该元数据被解释为不一致,并引发异常。实际上,每个套接字应该只打开一个输入流和一个输出流,并用一个ObjectStream覆盖每个流。如果您需要更多的流,请打开更多的套接字。根据您的系统,您可以同时打开100个(如果您真的需要…)