当前位置: 首页 > 面试题库 >

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

孙鑫鹏
2023-03-14
问题内容

我试图绕过 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<Integer, String>  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

问题答案:

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

您正在读取!=空值检查上的对象。您不打印它。然后,您尝试再次阅读它,它会炸弹。

从流中读取后,它就会被读取。它是流,而不是缓冲区。您可能想要缓冲读取的内容,然后可以根据需要检查该缓冲区。

最简单的例子

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


 类似资料:
  • 这是服务器类的代码。 如有任何帮助,不胜感激

  • 我试图理解ObjectInputStream/ObjectOutputStream,所以我创建了一个非常简单的服务器-客户端应用程序,其中客户端通过创建的流发送一个HashMap对象,服务器接收该对象并将其打印出来。 这是我的服务器代码: 这是我的客户代码: 我运行服务器文件,它运行正常。 然后我运行客户端文件,并在服务器上收到以下错误: 附言我不知道我是否必须做一些事情来序列化 HashMap,

  • 我正在应用程序的调查页面上运行负载测试。 对于200个用户,每秒1个循环通过测试180个用户,剩余20个用户低于异常。 请帮我修理。 我们使用Jmetm版本-3.2和JDK-8.2。我们已经按照代码在各自的文件。 httpclient4.retrycount=1,hc.parameters.file=hc.parameters在user.properties文件中添加代码,在hc.paramete

  • 更新:以下错误消息来自。 错误:服务器访问错误:连接重置URL=https://repo1.Maven.org/maven2/org/fusesource/jansi/jansi/1.11/jansi-1.11.pom Maven central:org/fusesource/jansi#jansi;1.11:res=https://repo1.Maven.org/maven2/org/fuses

  • 使用RxJS和Angular 2处理服务器重新连接的最佳方法是什么? 控制台中的结果: 如果我把这行替换掉.. 与 ...ServiceOnline仅在http服务返回成功响应且当前联机状态为false(断开连接)时发出另一个值: 所以TakeTaile应该有效。我在这里误解/遗漏了什么? 我是RxJS的新手--任何关于改进这段代码中实现的其他指针也将非常感谢...

  • 我在Spring上有一个拦截器,可以拦截用户的请求。我想计算申请的持续时间并保存到数据库中。然而,Spring不会自动连接我的豆子,导致服务上的空点异常。 这是代码: 我如何避免这个NPE?