【问题标题】:Cancel pending recv?取消挂起的接收?
【发布时间】:2018-12-24 23:57:06
【问题描述】:

您好,我正在做一个网络项目。我有一个正在监听传入数据的套接字。现在我要存档:Socket 将只接收 100 个数据包。并且有3-4个客户。他们无限地发送随机数据包。我将收到 100 个数据包,稍后我会处理它们。处理后我将重新开始接收。但此时有一些待处理的 send() >> recv() 操作。现在我想取消/放弃挂起的 recv 操作。我想我们会接收数据,我们不会处理它们。还有其他建议吗? (抱歉问题构成不好)

【问题讨论】:

  • 只是不要调用recv函数。操作系统会烧掉它们
  • @EdHeal 不会,除非接收者关闭套接字。
  • @EJP - 涉及超时机制。
  • @EdHeal 没有丢弃待处理数据的超时机制。

标签: c++ sockets networking


【解决方案1】:

关闭并关闭连接。这将立即取消所有内容。

更好的是,重新构建您的应用程序和网络协议,以便您可以可靠地判断要接收多少数据。

在 Windows 上,您可以使用 CancelIO 取消未完成的接收,但如果接收恰好读取了某些内容,则可能会导致数据丢失。

【讨论】:

  • 请参阅msdn.microsoft.com/en-us/library/windows/desktop/… 了解套接字关闭的工作原理。那里的信息 90% 是跨平台的,10% 是特定于 Windows 的。
  • 这几乎是正确的,只是在 Unix 上你必须这样做:signal(SIGPIPE, SIG_IGN);因为在另一个线程等待时关闭套接字会导致管道损坏。
【解决方案2】:

您可以使用select()poll() 循环。 你可以使用信号。 recv() 将在收到信号后返回,因此您可以将信号从另一个任务发送到阻塞 recv() 的任务。但是你需要确保你没有指定SA_RESTART(见http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html

阅读http://en.wikipedia.org/wiki/Asynchronous_I/O了解更多详情

【讨论】:

    【解决方案3】:

    我会选择非阻塞套接字 + 取消套接字。 您必须读入专用的增量缓冲区(因为 recv() 可能不会立即收到所有预期的数据 - 如果您只能处理完整的消​​息,就会出现这种情况)并返回到您的 select()/poll()循环,您可以安全地坐在那里等待:

    • 下一个数据
    • 下一个连接
    • 来自取消套接字的取消事件,您的其他线程将向该事件发送取消信号(一些微不足道的 send())。

    UPD:微不足道的事件可能是数组中套接字的编号或其句柄 - 用于确定您想取消哪一个。

    【讨论】:

    • 正确(但使用epoll()!)select()poll() 是古董。
    • 这对网络应用程序来说是正确的,但会使移植复杂化(如 WSAPoll(),类似于 poll() 仅出现在 Windows Vista 中)。因此,如果连接数可以很好地预测为 limited 并且跨平台性是问题所在 - 我会选择 select()。虽然你是对的 - 当涉及到无法控制的连接数量时,它的速度非常慢。
    • 好吧,有一些边缘情况
    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多