【问题标题】:What happens if one doesn't call POSIX's `recv` "fast enough"?如果一个人没有将 POSIX 的 `recv` 称为“足够快”,会发生什么?
【发布时间】:2011-01-15 16:53:30
【问题描述】:

我想考虑一种可能的情况,即我的 TCP/IP 流套接字服务的客户端向我的服务发送数据的速度比它设法将数据移动到其缓冲区(我自然是在谈论应用程序缓冲区)的速度更快,@987654321 @ 并使用它。

那么基本上,在这种情况下会发生什么?

显然,我的服务下的某种服务是用户应用程序,必须接收传入的流并将其存储在某个地方,直到我发出“recv”,对吗?肯定是操作系统。

我不想重新打开旧问题,但我似乎找不到这个看似显而易见的问题的答案?

【问题讨论】:

    标签: sockets berkeley-sockets


    【解决方案1】:

    TCP 提供 flow control 。 TCP 堆栈(在发送方和接收方)将能够为您缓冲一些数据,这通常在操作系统内核中完成。

    当接收缓冲区填满时,发送者会知道它,并停止发送更多数据,最终导致发送应用程序阻塞(或无法发送更多数据),直到空间再次可用。

    简而言之,发送的每个 TCP 数据包(段)都包含可以缓冲的数据大小 - 窗口大小。这意味着另一端始终知道它可以发送多少数据而接收器不会因为缓冲区已满而将其丢弃。如果窗口大小变为 0,则缓冲区已满,不再发送数据(如果发送方阻塞,send() 调用将阻塞),有探测 tcp 窗口是否仍为 0 的程序,所以发送数据消耗完后可以再次恢复。

    还有更多细节here

    【讨论】:

    • 不完全。每个 TCP 确认 都包含当前窗口大小。维基百科在这一点上是不正确的。正确的参考不是 Wikipedia,而是 RFC 793。
    • 缓冲区大小是否有任何近似值可以认为是典型/安全的?或者是不是太多样化了,无法做出这样的声明。
    【解决方案2】:

    它是维护数据缓冲区(包括用于传入数据的缓冲区)的网络驱动程序堆栈。如果缓冲区被填满,随后的 TCP 数据包将被丢弃,并且客户端在尝试发送数据时被卡住。 herehere 还有更多内容。

    【讨论】:

    • 没有。零窗口被通告给发送者并且发送者停止发送。最终,发送方的套接字发送缓冲区被填满,应用程序阻塞,除非它处于非阻塞模式,在这种情况下它会得到 EAGAIN 或 EWOULDBLOCK。只有当发送方没有正确实现 TCP 并发送到零大小的窗口时,TCP 数据包才会被丢弃。
    • @EJP 您的评论只是部分正确。在 IP 级别,数据包丢弃。我对 TCP 数据包的回复不正确(我猜是错字),但客户端仍然被阻止(即使有您的评论)。
    • 问题是关于 TCP 的。 TCP 段由 IP 数据包组成。在 IP 级别上,仅在发送封闭段时才丢弃数据包,并且仅在窗口允许时发送,而窗口不允许,因此不应发送。
    猜你喜欢
    • 1970-01-01
    • 2013-12-16
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    相关资源
    最近更新 更多