关于套接字:java.net.SocketException:连接重置

java.net.SocketException: Connection reset

我在尝试从套接字读取时遇到以下错误。我正在对该InputStream执行readInt(),并且遇到此错误。仔细阅读文档,这表明连接的客户端部分关闭了连接。在这种情况下,我是服务器。

我可以访问客户端日志文件,但它没有关闭连接,实际上它的日志文件表明我正在关闭连接。有人知道为什么会这样吗?还有什么要检查的?当有本地资源可能达到阈值时,会发生这种情况吗?

我确实注意到我有以下几行:

1
socket.setSoTimeout(10000);

readInt()之前。这是有原因的(长话短说),但出于好奇,在某些情况下这可能会导致指示的错误?我的服务器在IDE中运行,我碰巧将IDE卡在断点上,然后我发现完全相同的错误开始出现在我自己的IDE日志中。

无论如何,仅提及它,希望它不会成为鲱鱼。 :-(


有几种可能的原因。

  • 另一端故意重设了连接,在此我将不做记录。应用程序软件很少会这样做,而且通常是不正确的,但对于商业软件而言却并非未知。

  • 更常见的是,由于写入连接而导致另一端已经正常关闭。换句话说,应用程序协议错误。

  • 当套接字接收缓冲区中有未读数据时,关闭套接字也会导致此错误。

  • 在Windows中,"软件引起的连接中止"与"连接重置"不同,这是由您的终端发送的网络问题引起的。有关于此的Microsoft知识库文章。


  • 连接重置仅表示已收到TCP RST。当您的对等方收到无法处理的数据时,就会发生这种情况,并且可能有多种原因。

    最简单的方法是关闭套接字,然后在输出流上写入更多数据。通过关闭套接字,您告诉您的对等方您已经说完了,它可能会忘记您的连接。无论如何,当您在该流上发送更多数据时,对等方都会通过RST拒绝它,以让您知道它没有监听。

    在其他情况下,介入的防火墙甚至远程主机本身可能"忘记"您的TCP连接。如果长时间不发送任何数据(通常是2个小时),或者因为对等方已重新启动并丢失了有关活动连接的信息,则可能会发生这种情况。在这些无效连接之一上发送数据也会导致RST。

    更新以响应其他信息:

    仔细查看您对SocketTimeoutException的处理。如果在套接字操作上被阻止时超过了配置的超时,则会引发此异常。引发此异常时,套接字本身的状态不会更改,但是如果您的异常处理程序关闭了套接字,然后尝试对其进行写入,则您将处于连接重置状态。 setSoTimeout()旨在为您提供一种干净的方法来突破read()操作,否则该操作可能会永远阻塞,而无需执行诸如从另一个线程关闭套接字的肮脏的事情。


    每当遇到类似这样的奇怪问题时,我通常都会坐下来使用WireShark之??类的工具,查看来回传递的原始数据。在断开连接的地方您可能会感到惊讶,并且只有在尝试阅读时才会收到通知。


    您应该非常仔细地检查完整的跟踪,

    我有一个服务器套接字应用程序,并修复了java.net.SocketException: Connection reset的情况。

    在我的情况下,它发生在读取由于某种原因而关闭其连接的clientSocket Socket对象时。 (网络丢失,防火墙或应用程序崩溃或打算关闭)

    实际上,当我从此Socket对象读取错误时,我正在重新建立连接。

    1
    2
    3
    Socket clientSocket = ServerSocket.accept();
    is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    int readed = is.read(); // WHERE ERROR STARTS !!!

    有趣的是,如果客户端连接到我的ServerSocket并关闭其连接而没有发送任何内容,则for my JAVA Socket会递归地调用自身,这似乎是因为处于无限的while循环中,您尝试从该套接字读取封闭的连接。
    如果您使用类似下面的内容进行读取操作;

    1
    2
    3
    4
    while(true)
    {
      Receive();
    }

    然后你得到一个堆栈跟踪如下

    1
    2
    java.net.SocketException: Socket is closed
        at java.net.ServerSocket.accept(ServerSocket.java:494)

    我所做的只是关闭ServerSocket并更新我的连接,并等待进一步的传入客户端连接

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    String Receive() throws Exception
    {
    try {                  
                int readed = is.read();
               ....
    }catch(Exception e)
    {
            tryReConnect();
            logit(); //etc
    }


    //...
    }

    这可以重新建立我的连接,以防止未知的客户端套接字丢失

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private void tryReConnect()
            {
                try
                {
                    ServerSocket.close();
                    //empty my old lost connection and let it get by garbage col. immediately
                    clientSocket=null;
                    System.gc();
                    //Wait a new client Socket connection and address this to my local variable
                    clientSocket= ServerSocket.accept(); // Waiting for another Connection
                    System.out.println("Connection established...");
                }catch (Exception e) {
                    String message="ReConnect not successful"+e.getMessage();
                    logit();//etc...
                }
            }

    我找不到另一种方法,因为如您从下图看到的那样,如果没有try and catch,您将无法理解连接是否丢失,因为一切似乎都正确。我连续获取Connection reset时得到了此快照。

    enter image description here


    不好意思地说,但是当我遇到这个问题时,我在读取所有数据之前关闭连接只是一个错误。在返回小的字符串的情况下,它可以工作,但这可能是由于在关闭我的整个响应之前已将其缓冲了。

    如果返回的文本量较长,则会抛出异常,因为有更多的缓冲区返回。

    您可以检查此疏忽。记住,打开URL就像一个文件一样,请确保在完全读取它之后将其关闭(释放连接)。


    我有同样的错误。我现在找到了解决问题的方法。问题是客户端程序在服务器读取流之前已完成。


    我用Java编写的SOA系统遇到了这个问题。我在不同的物理计算机上同时运行客户端和服务器,并且它们在很长一段时间内都运行良好,然后那些讨厌的连接重置出现在客户端日志中,并且服务器日志中没有任何奇怪的地方。重新启动客户端和服务器都无法解决问题。最后,我们发现服务器端的堆已满,因此我们增加了JVM可用的内存:问题解决了!请注意,日志中没有OutOfMemoryError:内存只是稀缺,没有耗尽。


    我也有一个Java程序尝试通过SSH在服务器上发送命令的问题。问题出在执行Java代码的机器上。它没有连接到远程服务器的权限。 write()方法运行良好,但是read()方法抛出java.net.SocketException:连接重置。我通过将客户端SSH密钥添加到远程服务器已知密钥来解决此问题。


    检查服务器的Java版本。发生这种情况是因为我的Weblogic 10.3.6是在TLSv1上的JDK 1.7.0_75上。我尝试使用的其余端点关闭了低于TLSv1.2的任何内容。

    默认情况下,Weblogic试图协商最强的共享协议。在此处查看详细信息:设置HTTPS连接的https.protocols系统属性的问题。

    我添加了详细的SSL日志记录以标识受支持的TLS。这表明TLSv1正在用于握手。
    -Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

    我通过将功能推出到与JDK8兼容的产品中来解决了此问题,JDK8默认为TLSv1.2。对于限于JDK7的用户,我还通过升级到TLSv1.2成功地测试了Java 7的变通方法。我用了这个答案:如何在Java 7中启用TLS 1.2


    推荐阅读

      linux命令连接光驱?

      linux命令连接光驱?,系统,位置,设备,数据,电脑,服务,资料,盘中,智能,管理,Lin

      linux跳板机连接命令?

      linux跳板机连接命令?,地址,服务,密码,工具,中国,网络,位置,系统,电脑,在线,

      linux命令行拨号连接?

      linux命令行拨号连接?,系统,网络,软件,手机,服务,密码,地址,名称,电话号码,

      linux命令连接光驱?

      linux命令连接光驱?,系统,位置,设备,数据,电脑,服务,资料,盘中,智能,管理,Lin

      linux命令逻辑连接符?

      linux命令逻辑连接符?,系统,网络,名字,环境,信息,名称,设备,发行,位置,较大,L

      linux跳板机连接命令?

      linux跳板机连接命令?,地址,服务,密码,工具,中国,网络,位置,系统,电脑,在线,

      linux命令读取前十个?

      linux命令读取前十个?,时间,系统,最新,文件,名称,标准,密码,工作,适当,信息,l

      linux连接外网命令?

      linux连接外网命令?,网络,系统,工具,情况,软件,信息,地址,代理,地方,数据,请

      linux命令连接ip?

      linux命令连接ip?,地址,系统,网络,工作,信息,命令,密码,名称,设备,服务,linux

      linux读取码值命令?

      linux读取码值命令?,系统,工作,地址,证书,命令,工具,档案,文件,设计,信息,基

      linux命令错误代码?

      linux命令错误代码?,系统,密码,电脑,网络,手机,网址,软件,代码,设备,老板,Lin

      linux重置网络命令?

      linux重置网络命令?,网络,地址,工作,环境,系统,信息,标准,设备,命令,工具,lin

      linux蓝牙重置命令?

      linux蓝牙重置命令?,工作,系统,地址,手机,信息,蓝牙,各大,命令,密码,标准,lin

      linux命令连接网址?

      linux命令连接网址?,网址,系统,地址,服务,传播,数据,命令,名字,环境,网站,如

      linux连接多条命令?

      linux连接多条命令?,工具,情况,命令,分行,服务,地址,连续,终端,窗口,主机,lin

      linux有线网连接命令?

      linux有线网连接命令?,系统,网络,软件,电脑,密码,地址,信息,虚拟机,终端,命

      linux编译连接命令?

      linux编译连接命令?,系统,代码,环境,工具,文件,资料,电脑,百度,终端,命令,在l

      linux上的软连接命令?

      linux上的软连接命令?,系统,设备,位置,链接,文件,数据,交通,地方,信息,地址,L

      linux命令忽略错误?

      linux命令忽略错误?,系统,地址,工作,信息,设备,命令,设计,灵活,观察,标准,lin

      mac命令连接linux?

      mac命令连接linux?,系统,软件,电脑,密码,公司,网络,地址,通用,服务,发展,macb