我正在编写服务器客户端应用程序。客户端通过不同的流向服务器发送某种数据。一旦我把这样的流放在主方法中,程序就什么也不做;没有例外,只是空控制台:
try {
socket = new Socket("localhost", 4050);
din = new DataInputStream(socket.getInputStream());
oin = new ObjectInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
System.out.println("Exception: the host is unknown");
} catch (IOException e) {
System.out.println("I/O exception thrown by socket");
}
一旦我从主方法的那个部分删除了这个流oin = new ObjectInputStream(socket.getInputStream());
,程序就会抛出EOFException或连接重置异常。上面的代码有什么特别之处,以至于程序什么都不做,也不抛出异常?
一旦你将提到的流放入一个单独的方法
private static MessageObject readObject(){
MessageObject mo = null;
try{
oin = new ObjectInputStream(socket.getInputStream());
mo = (MessageObject)oin.readObject();
}
catch(IOException e){
System.err.println(e.getCause());
}
catch(ClassNotFoundException e){
System.err.println(e.getCause());
}
return mo;
}
它抛出了这个异常:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readBoolean(Unknown Source)
at Server.main(Server.java:77)
在服务器上,它在if分支上:
if (din.readBoolean()) {
ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
MessageObject o = (MessageObject)oin.readObject();
// server saves the whole thing
MessageDB.add(o);
}
我不能把我所有的代码都放在这里,这是我的任务。
哦,对不起,人们,错误已经找到了。一些逻辑错误,服务器期望一些输入,但客户端拒绝发送。
您在这里犯了几个错误。
-
您正在同一套接字上使用多个流。不要那样做,他们只会互相混淆。当您需要对象I/O时,只需对所有内容使用
ObjectInputStream
和ObjectOutputStream
即可。 -
施工顺序不正确。必须在两端的
ObjectInputStream
之前构造ObjectOutputStream
。 -
您使用的流具有不同的生存期。你还没有解决这个问题,但最终这将导致
StreamCorruptedException
。在套接字的使用寿命内,在两端使用相同的ObjectInputStream
和ObjectOutputStream
。 -
您可能还需要阅读
ObjectOutputStream.reset()
和.writeUnshared()
的Javadoc,以了解它们的作用,以及为什么您可能需要调用其中一个或另一个。