gpt4 book ai didi

Java TLS 套接字写入无法检测连接重置

转载 作者:太空宇宙 更新时间:2023-11-04 10:07:58 25 4
gpt4 key购买 nike

我正在努力及时检测 Java TLS 套接字上的连接重置。

我正在处理一个丢失消息的 syslog-over-TLS 客户端。系统日志客户端在消息到达时发送消息,并为此目的保持单个 TLS 套接字打开,除非出现错误,在这种情况下,它将丢弃套接字并打开新连接。

为了调查这个问题,我一遍又一遍地发送相同类型和大小的消息。

发生的情况如下:

  1. 启动客户端
  2. 第一条消息到达 - 新套接字已打开,消息已成功传输到远程系统日志(代码如下)
  3. 闲置 15 分钟
  4. 第二条消息到达 - 现有套接字用于发送消息;收到tcp连接重置但没有抛出异常;消息丢失
  5. 第三条消息不久后到达 - 写入套接字立即失败并出现异常:连接重置;客户端打开新套接字并成功发送消息

发送消息的代码(太?)简单:

OutputStream out = socket.getOutputStream();
out.write(syslogFrame);
out.write(msgBytes);
out.flush();

为什么上面代码中的第二次写入操作最晚在第二条消息上没有收到异常?我怎样才能确保我做到了?

该消息明显大于 MTU,并且 I/O 图表非常清楚地显示第二条消息甚至无法通过网络传输:

enter image description here

完整跟踪:连接是在数据包 #2 处建立的。 #27 之前的数据包是第一条消息的传输。 #28、#29、#30 是连接重置应答的第二条消息的开头。此时 Java 代码中不会引发异常。套接字写入操作返回且没有错误,但消息丢失。第三条消息的写入操作现在收到连接重置异常,这会触发客户端代码在数据包 #33 ff 中重新建立连接,然后第三条消息将通过网络传输。

enter image description here

我运行客户端的操作系统是Linux Mint 18.3(内核4.10.0-38-generic),带有Oracle JDK 1.8.0_172和10.0.2; CentOS Linux 7.5.1804(内核3.10.0-693.21.1.el7.x86_64)和Oracle JDK 1.8.0_172。

最佳答案

这个问题实际上是 TCP 上实现的所有单工协议(protocol)所固有的。而且,由于 Java 中的写入往往会在任何字节实际压入 TCP 堆栈之前返回,这一事实在某种程度上加剧了这种情况。甚至在 flush() 上也不行。因此,信号发送在设计上是不可靠的。

确定套接字连接健康状况的唯一可靠方法是读取它。但对于单工协议(protocol)来说,没有什么可读的。这就是为什么 rsyslog 实现 RELP protocol它添加了一个反向 channel ,通过该反向 channel 发送应用程序级 ACK/NAK 消息。

关于Java TLS 套接字写入无法检测连接重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52705549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com