SocketException:使用ObjectInputStream在服务器上重置连接

我试图绕过ObjectInputStream / ObjectOutputStream ,所以我创建了一个非常简单的服务器 – 客户端应用程序,客户端通过创建的流发送HashMap对象,服务器接收并打印出来。

这是我的服务器代码:

import java.io.*; import java.net.*; public class Server { public static void main(String[] args) throws IOException, ClassNotFoundException { ServerSocket server = new ServerSocket(4444); while (true) { Socket socket = server.accept(); ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream()); if (objIn.readObject() != null) { System.out.println(objIn.readObject()); } } } } 

这是我的客户端代码:

 import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.util.HashMap; public class Client { public static void main(String[] args) throws IOException { Socket sock; int port = 4444; HashMap mapSend= new HashMap(); mapSend.put(1,"row1"); mapSend.put(2,"row2"); sock = new Socket(InetAddress.getLocalHost(), port); ObjectOutputStream objOut = new ObjectOutputStream(sock.getOutputStream()); objOut.writeObject(mapSend); objOut.flush(); } } 

我运行服务器文件,它运行正常。
然后我运行客户端文件,我在服务器上收到以下错误:

  Exception in thread "main" java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2308) at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2716) at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:2740) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1978) at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:499) at java.util.HashMap.readObject(HashMap.java:1115) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1891) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) at iotest.Server.main(Server.java:17) Java Result: 1 

PS我不知道是否必须要做一些事情来序列化HashMap,但我想我在某处看到这是由Java内部处理的。 我可能很难错。

在Aaron回答之后编辑我在我的服务器中实现了这个部分,因为Aaron建议:

 Object objRead=objIn.readObject(); if (objRead != null) { System.out.println(objRead); } 

现在我在运行客户端后再次从服务器收到此错误:

 Exception in thread "main" java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2308) at java.io.ObjectInputStream$BlockDataInputStream.read(ObjectInputStream.java:2716) at java.io.ObjectInputStream$BlockDataInputStream.readFully(ObjectInputStream.java:2740) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1978) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1913) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) at java.util.HashMap.readObject(HashMap.java:1154) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1891) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1796) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) at iotest.Server.main(Server.java:17) Java Result: 1 

您正在读取对象两次,但仅打印第二次。 因此,当您尝试第二次读取时,客户端可能会关闭,因此套接字已在远程端关闭,因此exception。

您正在读取!= null检查中的对象。 你不打印它。 然后你试着再次读它并炸弹。

从流中读取后,它已被读取。 它是一个流,而不是缓冲区。 您可能希望缓冲读取,然后您可以根据需要检查该缓冲区。

最简单的例子……

 Object o = outputStream.readObject(); if(o != null) { system.out.println(o); } 

发生这种情况是因为客户端套接字在执行完所有代码后自动终止。

例如,如果添加

 while (true) { System.out.println("no operation"); try { Thread.sleep(10000); } catch(InterruptedException e) { e.printStackTrace(); } } 

在客户端代码的末尾,您没有得到任何连接重置,因为您的客户端套接字永远不会被终止。

因此,客户端套接字关闭,服务器端套接字必须处理此exception。 当你遇到这个exception时,你应该从循环中走出来,所以:

 boolean connected = true; while (connected) { try { //your code } catch (SocketException e) { connected = false; } }