0

从 libevent 文档中,我了解到当从远程对等方接收到 TCP 段时,会生成 EV_READ 事件。在以下场景中会发生什么

  1. 已在套接字上注册了读取和写入事件的非阻塞应用程序
  2. 场景 A:应用程序正在等待一个事件。它从远程获取 FIN,生成 EV_READ 事件,应用程序执行读取(或接收)并获取 0
  3. 场景 B:应用程序正在发送数据。它在执行发送从远程获取 FIN 。应用程序是否会获得 EPIPE(我认为是这样)。是否还会为应用程序获取 EPIP 的同一 FIN 生成 EV_READ 事件

一个相关的问题是,如果 send 和 write 与本文中提到的相似,那么为什么 ECONNRESET 没有像这里的手册页那样在 write 中生成,而是按照手册页中描述在 send 中生成。

如何编写远程对等体,以便本地发送返回 ECONNRESET。感谢您的任何回答

4

1 回答 1

3

场景 A:应用程序正在等待一个事件。它从远程获取 FIN,EV_READ 事件 > 生成,应用程序执行读取(或接收)并获取 0

是的,这是正确的。

场景 B:应用程序正在发送数据。当发送正在执行时,它会从远程获得一个 FIN。应用程序是否会获得 EPIPE(我认为是这样)。是否还会为应用程序获得 EPIPE 的相同 FIN 生成 EV_READ 事件

是的,将生成一个 EV_READ 事件。(当然前提是您同时没有关闭()套接字)。

但是,在这种非常特殊的情况下,您不会收到写入错误。当你从对端得到一个 FIN 时,TCP 连接只是半关闭。传入的 FIN 仅表示“我没有更多要发送”。但是您可以向它发送更多数据。或者您可以关闭()套接字,从而导致从您这边到对等方的 FIN,现在 TCP 连接被认为是关闭的,因为你们都发送了 FIN 数据包。

此时,这取决于对等方实际做了什么,是调用 close() 还是 shutdown()。在随后的 write() 中,如果对等应用程序关闭其套接字并且对等发送了 RST,您可能会得到 EPIPE 或 ECONNRESET,或者如果对等已被编码为接收更多数据,您可能会继续向其发送数据。

请注意,您只是在描述一种特殊情况。根据时间和网络或对等点上发生的情况,还有很多很多情况需要考虑。

如何编写远程对等体,以便本地发送返回 ECONNRESET。

如果对等方在对等方的本地缓冲区中仍有数据要读取时执行 close(),则会发生这种情况。在这种情况下,发送 RST,写入/发送会因 ECONNRESET 出错,read()/recv() 也会出错。

要生成这种情况,只需不要 read() 任何东西,稍等片刻,直到您确定某些数据已经到达,然后 close() 套接字。另一端稍后的 write() 将获得 ECONNRESET。ECONNRESET 之后的另一个 write() 应该得到 EPIPE。

于 2013-06-28T17:52:35.653 回答