java - 由于服务器关闭套接字而导致写入失败时,Netty 无法从服务器读取字节

标签 java sockets netty

Netty版本:4.0.10.Final

我使用 Netty 编写了客户端和服务器。这是客户端和服务器所做的事情。

服务器:

  1. 等待客户端连接
  2. 接收来自客户端的消息
  3. 如果消息错误,写入错误消息(6字节),刷新它, 关闭套接字并且不读取套接字中任何未读的消息。 否则继续阅读消息。不要对好消息采取任何行动。

客户:

  1. 连接到服务器。
  2. 写完 N 条好消息后,写一条坏消息并继续 写M条好消息。这个过程发生在一个单独的线程中。 该线程在 channel 处于 Activity 状态后启动。
  3. 如果服务器有任何响应,记录它并关闭 socket 。 (请注意,服务器仅在出现错误时响应)

我已经追踪了客户端和服务器。我发现服务器在写入错误消息后正在关闭连接。当在坏消息之后写入好消息时,客户端开始看到损坏的管道错误。这是因为服务器检测到错误消息并响应错误消息并关闭套接字。仅当使用监听器完成写入操作后,连接才会关闭。客户端并不总是从服务器读取错误消息。客户端中前面的步骤 (2) 是在 I/O 线程中执行的。这导致在 K 次实验中收到的错误消息百分比非常低 (<10%)。将步骤 (2) 移至单独线程后,% 变为 (70%)。无论如何,它都是不准确的。如果由于管道损坏导致写入失败,netty 是否会触发 channel 读取?

更新 1: 我正在澄清并回答此处提出的任何问题,以便每个人都可以在一处找到所提出的问题/澄清。 “你正在写一条会导致重置的坏消息,然后是你已经知道不会通过的好消息,并试图阅读可能已被丢弃的回复。这对我来说没有任何意义无论如何” - 来自 EJP

-- 在现实世界中,服务器可能会因为客户端无法提前知道的任何原因而将某些内容视为不良内容。为了简单起见,我说客户端故意发送一条错误消息,导致服务器重置。即使消息总数中有坏消息,我也愿意发送所有好的消息。

我正在做的事情类似于 Apple Push Notification Service 实现的协议(protocol).

最佳答案

If a message is bad, write error message (6 bytes), flush it, close the socket and do not read any unread messages in the socket. Otherwise continue reading messages.

这将导致连接重置,这将被客户端视为 Unix、Linux 等中的管道损坏。

After writing N good messages, write one bad message and continue writing M good messages.

那就会遇到刚才提到的broken pipeline错误。

This process happens in a separate thread.

为什么? NIO 以及 Netty 的全部意义在于您不需要额外的线程。

I've found that server is closing connection after writing the error message.

嗯,这就是你所说的,所以它就是这样做的。

Client began seeing broken pipe errors when writing good messages after the bad message.

正如我所说。

This is because server detected bad message and responded with error message and closed socket.

正确。

Client is not reading error message from server always.

由于连接重置。重置后,待处理数据的传送将停止。

Does netty trigger channel read if the write fails due to broken pipe?

不是,当数据或EOS到达时触发读取

然而,你奇怪的系统设计/协议(protocol)使得这种情况即使不是不可能,也是不可预测的。您正在编写一条会导致重置的坏消息,然后是您已经知道不会通过的好消息,并尝试读取可能已被丢弃的响应。这对我来说没有任何意义。你想在这里证明什么?

像其他人一样尝试请求-响应协议(protocol)。

关于java - 由于服务器关闭套接字而导致写入失败时,Netty 无法从服务器读取字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19368347/

相关文章:

java - 文件输入流和文件输出流

sockets - Swift 中的 TCP 套接字

sockets - 测试套接字服务器的最佳实践?

java - 一段时间后,Netty 客户端不会发送更多数据

java - osmdroid 上的多个图 block 层

使用 PreparedStatement 的 Java 多线程和连接池

从性能pov看Java静态代码分析

c - 套接字编程 - 具有客户端和服务器代码的进程

java - 无法在 Java 7 上启用 SNI

java - Netty HTTP 输出到 HTML\jsp