首页 文章

java.net.SocketException:连接重置

提问于
浏览
92

我试图从套接字读取时出现以下错误 . 我在 InputStream 上做 readInt() ,我收到了这个错误 . 仔细阅读文档,这表明连接的客户端部分关闭了连接 . 在这种情况下,我是服务器 .

我可以访问客户端日志文件并且它没有关闭连接,事实上它的日志文件建议我关闭连接 . 所以有人知道为什么会这样吗?还有什么要检查的?当有可能达到阈值的本地资源时,是否会出现这种情况?


我注意到我有以下几行:

socket.setSoTimeout(10000);

就在 readInt() 之前 . 这是一个原因(长篇故事),但只是好奇,是否存在这可能导致指示错误的情况?我在我的IDE中运行了服务器,我碰巧让我的IDE卡在断点上,然后我注意到完全相同的错误开始出现在我自己的IDE中 .

无论如何,只要提一下,希望不是红鲱鱼 . :-(

8 回答

  • 1

    我用Java编写的SOA系统遇到了这个问题 . 我在不同的物理机器上运行客户端和服务器并且它们工作了很长时间,然后在客户端日志中出现了那些讨厌的连接重置,并且服务器日志中没有任何异常 . 重新启动客户端和服务器并没有解决问题 . 最后我们发现服务器端的堆相当充满,所以我们增加了JVM可用的内存:问题解决了!请注意,日志中没有OutOfMemoryError:内存很少,没有用尽 .

  • 92

    有几种可能的原因 .

    • 另一端故意重置连接,我不会在这里记录 . 对于应用程序软件来说,这种情况很少见,而且通常是不正确的,但商业软件并不为人所知 .

    • 更常见的是,它是通过写入另一端已正常关闭的连接引起的 . 换句话说,应用程序协议错误 .

    • 当套接字接收缓冲区中存在未读数据时,也可能由关闭套接字引起 .

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

  • 7

    你应该仔细检查完整的痕迹,

    我有一个服务器套接字应用程序并修复了 java.net.SocketException: Connection reset 案例 .

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

    实际上,当我从这个Socket对象读取错误时,我正在重新 Build 连接 .

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

    有趣的是 for my JAVA Socket 如果一个客户端连接到我的 ServerSocket 并关闭它的连接而没有发送任何 is.read() 本身的递归调用 . 它似乎是因为在一个无限的while循环中从这个套接字读取你尝试从一个封闭的连接读取 . 如果您使用类似下面的内容进行读取操作;

    while(true)
    {
      Receive();
    }
    

    然后你会得到一个类似下面的stackTrace

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

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

    String Receive() throws Exception
    {
    try {                   
                int readed = is.read();
               ....
    }catch(Exception e)
    {
            tryReConnect();
            logit(); //etc
    }
    
    
    //...
    }
    

    这重新 Build 了我对未知客户端套接字丢失的连接

    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 ,我无法理解连接是否丢失,因为一切似乎都是正确的 . 我连续收到_35865时得到了这个快照 .

  • 36

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

  • 7

    令人尴尬地说出来,但是当我遇到这个问题时,我在阅读所有数据之前关闭连接只是一个错误 . 在返回小字符串的情况下,它可以工作,但这可能是由于整个响应被缓冲,然后我关闭它 .

    如果返回的文本数量较长,则抛出异常,因为更多的缓冲区将返回 .

    你可能会检查这个疏忽 . 请记住,打开一个URL就像一个文件,一旦完全读取,请务必关闭它(释放连接) .

  • 5

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

  • 10

    每当我遇到像这样的奇怪问题时,我通常会坐下来使用像WireShark这样的工具来查看来回传递的原始数据 . 如果事情被断开,你可能会感到惊讶,而你只是当你尝试阅读时收到通知 .

  • 4

    连接重置只是意味着收到了TCP RST . 当您的对等方接收到无法处理的数据时会发生这种情况,并且可能有多种原因 .

    最简单的方法是关闭套接字,然后在输出流上写入更多数据 . 通过关闭套接字,你告诉你的同伴你已经完成了谈话,它可以忘记你的连接 . 当您在该流上发送更多数据时,对等方使用RST拒绝它,让您知道它没有收听 .

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


    更新以回应其他信息:

    仔细看看你对 SocketTimeoutException 的处理 . 如果在套接字操作上阻止配置的超时,则会引发此异常 . 抛出此异常时,套接字本身的状态不会更改,但如果您的异常处理程序关闭套接字,然后尝试写入它,则您将处于连接重置状态 . setSoTimeout() 旨在为您提供一种简洁的方法来打破 read() 操作,否则可能永远阻塞,而不会像从另一个线程关闭套接字那样做脏事 .

相关问题