带有非阻塞套接字的libevent:如果远程对等体发送RST *而*执行本地发送,则本地获取EV_READ也是

时间:2013-06-28 12:20:36

标签: sockets send recv libevent

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

  1. 已在套接字上注册读取和写入事件的非阻止应用程序
  2. 场景A:应用程序正在等待事件。它从远程获取FIN,生成EV_READ事件,应用程序执行读取(或recv)并获取0
  3. 场景B:应用程序正在发送数据。它从远程获取FIN,而正在执行发送。应用程序是否会获得EPIPE(我想是这样)。是否还会为应用程序获取EPIP的同一FIN生成EV_READ事件
  4. 一个相关的问题是,如果发送和写入与this中提到的类似,那么为什么ECONNRESET不会像手册页here那样在写入中生成,而是按照手册中的描述在send中生成第here页。

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

1 个答案:

答案 0 :(得分:3)

  

场景A:应用程序正在等待事件。它从远程获取FIN,生成EV_READ事件,应用程序执行读取(或recv)并获取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()也是如此。

要生成这种情况,只需不要读取()任何内容,等待一段时间,直到确定某些数据已到达,然后关闭()套接字。稍后的另一端的write()将获得ECONNRESET。 ECONNRESET之后的另一个write()应该获得EPIPE。