找回密码
 立即注册
查看: 392|回复: 0

[后端] javax.net.ssl.SSLException:closing inbound before receiving peer‘s close_notify

[复制链接]

224

主题

0

回帖

773

积分

高级会员

积分
773
发表于 2024-6-30 11:58:48 | 显示全部楼层 |阅读模式
本帖最后由 御坂主机 于 2024-7-3 18:23 编辑

1. 概述

在使用java进行网络编程时,可能会遇到各种SSL/TLS相关的问题。其中一个常见的错误是“javax.net.ssl.SSLException: closing inbound before receiving peer‘s close_notify”。这个错误通常出现在SSL连接的关闭过程中,表示在接收到对等方的`close_notify`消息之前关闭了输入流。本文将详细介绍该错误的原因及解决方案。

1.1 错误背景

SSL/TLS协议在关闭连接时,要求通信双方发送并接收`close_notify`消息,以确保连接的有序关闭。如果在接收对等方的`close_notify`消息之前关闭了输入流,就会引发`javax.net.ssl.SSLException: closing inbound before receiving peer‘s close_notify`错误。这种情况可能出现在客户端或服务器端。

1.2 解决方案概述

为了解决这一问题,我们需要确保在关闭SSL连接时正确处理`close_notify`消息。具体的解决方案包括正确关闭连接、捕获并处理异常等。本文将详细介绍这些解决方案,并提供相应的代码示例。

2. 正确关闭SSL连接

2.1 客户端正确关闭连接

在客户端程序中,正确关闭SSL连接可以避免该错误。以下是一个示例,展示了如何在客户端中正确关闭SSL连接:

  1.     import javax.net.ssl.SSLSocket;
  2.     import javax.net.ssl.SSLSocketFactory;
  3.     import java.io.OutputStream;
  4.     import java.io.InputStream;

  5.     public class SSLClient {
  6.         public static void main(String[] args) {
  7.             try {
  8.                 SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
  9.                 SSLSocket socket = (SSLSocket) factory.createSocket("localhost", 8443);

  10.                 OutputStream outputStream = socket.getOutputStream();
  11.                 InputStream inputStream = socket.getInputStream();

  12.                 // 发送数据
  13.                 outputStream.write("Hello Server".getBytes());
  14.                 outputStream.flush();

  15.                 // 读取服务器响应
  16.                 byte[] buffer = new byte[1024];
  17.                 int bytesRead = inputStream.read(buffer);
  18.                 System.out.println(new String(buffer, 0, bytesRead));

  19.                 // 关闭输出流,触发发送close_notify消息
  20.                 socket.getOutputStream().close();

  21.                 // 关闭输入流,确保接收服务器的close_notify消息
  22.                 socket.getInputStream().close();

  23.                 socket.close();
  24.             } catch (Exception e) {
  25.                 e.printStackTrace();
  26.             }
  27.         }
  28.     }
复制代码


在上述代码中,`socket.getOutputStream().close()`用于关闭输出流,触发发送`close_notify`消息;`socket.getInputStream().close()`确保接收服务器的`close_notify`消息,然后关闭输入流。

2.2 服务器正确关闭连接

在服务器程序中,同样需要正确关闭SSL连接。以下是一个示例,展示了如何在服务器中正确关闭SSL连接:

  1.     import javax.net.ssl.SSLServerSocket;
  2.     import javax.net.ssl.SSLServerSocketFactory;
  3.     import javax.net.ssl.SSLSocket;
  4.     import java.io.OutputStream;
  5.     import java.io.InputStream;

  6.     public class SSLServer {
  7.         public static void main(String[] args) {
  8.             try {
  9.                 SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
  10.                 SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8443);

  11.                 while (true) {
  12.                     SSLSocket socket = (SSLSocket) serverSocket.accept();

  13.                     OutputStream outputStream = socket.getOutputStream();
  14.                     InputStream inputStream = socket.getInputStream();

  15.                     // 读取客户端数据
  16.                     byte[] buffer = new byte[1024];
  17.                     int bytesRead = inputStream.read(buffer);
  18.                     System.out.println(new String(buffer, 0, bytesRead));

  19.                     // 发送响应
  20.                     outputStream.write("Hello Client".getBytes());
  21.                     outputStream.flush();

  22.                     // 关闭输出流,触发发送close_notify消息
  23.                     socket.getOutputStream().close();

  24.                     // 关闭输入流,确保接收客户端的close_notify消息
  25.                     socket.getInputStream().close();

  26.                     socket.close();
  27.                 }
  28.             } catch (Exception e) {
  29.                 e.printStackTrace();
  30.             }
  31.         }
  32.     }
复制代码


在上述代码中,同样通过关闭输出流和输入流,确保在关闭连接时正确处理`close_notify`消息。

3. 捕获并处理异常

在某些情况下,即使按照上述方法关闭连接,仍可能遇到`javax.net.ssl.SSLException: closing inbound before receiving peer‘s close_notify`错误。此时,可以通过捕获并处理该异常来确保程序的稳定性。

  1.     try {
  2.         // 关闭输出流,触发发送close_notify消息
  3.         socket.getOutputStream().close();

  4.         // 关闭输入流,确保接收对等方的close_notify消息
  5.         socket.getInputStream().close();
  6.     } catch (SSLException e) {
  7.         // 捕获并处理SSLException
  8.         if (!"closing inbound before receiving peer's close_notify".equals(e.getMessage())) {
  9.             throw e;
  10.         }
  11.     }
复制代码


在上述代码中,通过捕获`SSLException`,并检查错误消息内容,忽略特定的错误,从而确保程序不会因为未接收到`close_notify`消息而中断。

4. 总结

通过本文的介绍,我们详细了解了`javax.net.ssl.SSLException: closing inbound before receiving peer‘s close_notify`错误的原因及解决方案。无论是通过正确关闭SSL连接,还是捕获并处理异常,都可以有效地解决该错误。在实际开发中,了解并掌握这些技巧,可以帮助我们编写更健壮的网络程序,避免因SSL/TLS相关问题导致的程序中断。希望本文的介绍能够帮助大家解决这一常见的SSL错误,更好地进行Java网络编程。






------------------------------------------------------------------------------------------------------------------------------------------

========  御 坂 主 机  ========

>> VPS主机 服务器 前沿资讯 行业发布 技术杂谈 <<

>> 推广/合作/找我玩  TG号 : @Misaka_Offical <<

-------------------------------------------------------------------------------------------------------------------------------------------

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

联系站长|Archiver|手机版|小黑屋|主机论坛

GMT+8, 2025-4-4 13:35 , Processed in 0.071239 second(s), 24 queries .

Powered by 主机论坛 HostSsss.Com

HostSsss.Com

快速回复 返回顶部 返回列表