有没有办法阻塞在套接字send(),直到我们得到该包的ack? [英] Is there a way to block on a socket send() until we get the ack for that packet?

查看:395
本文介绍了有没有办法阻塞在套接字send(),直到我们得到该包的ack?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

还是我必须在应用程序级别实现它?

解决方案

TCP通常会要求您同步接收器和发件人在应用程序级别。 SO_SNDBUF 的组合或调整或 TCP_NODELAY 不可能完全解决问题。这是因为在 send()之前可以在飞行中的数据量将大致等于以下的总和:


  1. 发送端的发送缓冲区中的数据,包括小于a的数据片段 Nagle的算法

  2. 未确认的飞行包中携带的数据量,随拥塞窗口 CWIN )和接收窗口( RWIN )尺寸。当TCP在慢启动,拥塞避免,快速恢复和快速重传模式之间转换时,TCP发送器连续地将拥塞窗口大小调整到网络条件。和

  3. 接收端的接收缓冲区中的数据,接收方的TCP堆栈已经发送了 ACK ,但是


  4. 换句话说,在接收器停止从套接字读取数据之后, send()只会阻止:


    1. 接收器的TCP接收缓冲区填充, $ c> ACK ing,

    2. 发送者发送un ACK 窗口限制和

    3. 发件人的TCP发送缓冲区已满或发件人应用程序请求发送缓冲区冲洗。

    TCP中使用的算法的目标是创建流的字节流而不是包序列的效果。一般来说,它试图尽可能地隐藏传输被量化为分组的事实,并且大多数套接字API反映了这一点。这样做的一个原因是,socket可能不是在顶端TCP(或甚至IP)上实现的:考虑使用相同API的Unix域套接字。



    尝试依赖TCP的底层实现细节的应用程序行为通常是不可取的。坚持在应用程序层同步。



    如果延迟是您正在进行同步的情况下的一个问题,您可能还想阅读关于 Nagle的算法与延迟 ACK 之间的互动可能会导致不必要的在某些情况下延迟。


    Or do I have to implement it at the application level?

    解决方案

    TCP will in general require you to synchronize the receiver and sender at the application level. Combinations of SO_SNDBUF tweaking or TCP_NODELAY alone are not likely solve the problem completely. This is because the amount of data that can be "in flight" before send() will block is more or less equal to the sum of:

    1. The data in the transmit side's send buffer, including small data fragments being delayed by Nagle's algorithm,
    2. The amount of data carried in unacknowledged in-flight packets, which varies with the congestion window (CWIN) and receive window (RWIN) sizes. The TCP sender continuously tunes the congestion window size to network conditions as TCP transitions between slow-start, congestion avoidance, fast-recovery, and fast-retransmit modes. And,
    3. Data in the receive side's receive buffer, for which the receiver's TCP stack will have already sent an ACK, but that the application has not yet seen.

    To say it another way, after the receiver stops reading data from the socket, send() will only block when:

    1. The receiver's TCP receive buffer fills and TCP stops ACKing,
    2. The sender transmits unACKed data up to the congestion or receive window limit, and
    3. The sender's TCP send buffer fills or the sender application requests a send buffer flush.

    The goal of the algorithms used in TCP is to create the effect of a flowing stream of bytes rather than a sequence of packets. In general it tries to hide as much as possible the fact that the transmission is quantized into packets at all, and most socket APIs reflect that. One reason for this is that sockets may not be implemented on top TCP (or indeed even IP) at all: consider a Unix domain socket, which uses the same API.

    Attempting to rely on TCP's underlying implementation details for application behavior is generally not advisable. Stick to synchronizing at the application layer.

    If latency is a concern in the situation where you're doing the synchronization, you may also want to read about interactions between Nagle's algorithm and delayed ACK that can introduce unnecessary delays in certain circumstances.

    这篇关于有没有办法阻塞在套接字send(),直到我们得到该包的ack?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆