当前位置: 首页 > 知识库问答 >
问题:

SocketExc的:连接重置服务器上的ObjectInpuStream

慕容晔
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

附言我不知道我是否必须做一些事情来序列化 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

共有2个答案

阚砚文
2023-03-14

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

例如,如果您添加

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

在客户端代码结束时,不会获得任何连接重置,因为客户端套接字永远不会终止。

因此,客户端套接字是关闭的,服务器端套接字必须处理这个异常。当你得到这个异常时,你应该退出循环,所以:

boolean connected = true;
while (connected) {
    try {
        //your code
    } catch (SocketException e) {
        connected = false;
    }
}
洪承天
2023-03-14

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

您正在读取上的一个对象!=空检查。你不要打印出来。然后你试着再读一遍,它就爆炸了。

一旦你从流中读取,它就被读取了。这是一个流,不是缓冲区。您可能想要缓冲读取,然后您可以尽可能多地检查该缓冲区。

最简单的例子…

Object o = outputStream.readObject();
if(o != null) {
 system.out.println(o);
}
 类似资料:
  • 问题内容: 我试图绕过 ObjectInputStream / ObjectOutputStream ,所以我创建了一个非常简单的服务器- 客户端应用程序,其中客户端通过创建的流发送HashMap对象,服务器接收并打印该对象。 这是我的服务器代码: 这是我的客户代码: 我运行服务器文件,它运行正常。 然后运行客户端文件,并在服务器上收到以下错误: PS我不知道我是否需要做一些事情来序列化HashM

  • 更新:以下错误消息来自。 错误:服务器访问错误:连接重置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

  • 因此,最近我将我的服务(用Java编写)从AWS迁移到了GCP。我的一个服务通过HTTP(java HttpClient)与其他服务(都在GCP中)交互。一个非常奇怪的行为发生在我随机获得java.net.socketException:连接重置的地方,比如:- 由:java.net.socketException:java.net.socketInputStream.read(SocketInp

  • 在登录时出现: 或 登录时如果出现上图的错误,通常有如下原因: 1、IIS没有正常启动。 正常启动应如下图所示: 2、服务器有防火墙,请关闭防火墙 或者 开放 80 端口(或你设置的其它的端口号)。 上图就是操作系统自带防火墙开放80端口的操作界面,如果有第三方的防火墙也必须这么做。 3、验证客户端与服务器的通讯是否正常,可以在客户机上打开IE浏览器,在地址栏中输入:http://网络服务器的IP

  • 问题内容: 我想编写一个脚本来测试所有链接的服务器,并返回唯一已连接的服务器(可以肯定只有一个)。 这是我当前的脚本,但是我被困在这一点上: 但是使用此查询,代码无法在第一次迭代时停止,因为它无法连接到表的第一台服务器。这是错误消息: 链接服务器“ server1”的OLE DB提供程序“ MSDASQL”返回了消息“通信链接失败; -10709连接失败(连接超时已过期)”。消息7303,级别16

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