如何在继续之前显式等待TCP确认?

如何在继续之前显式等待TCP确认?,c,tcp,sockets,C,Tcp,Sockets,有没有办法让send()等待所有已发送的数据都已确认(如果已达到确认超时,则返回-1),或者有其他机制在发送()之后但在执行其他操作之前等待确认 我使用的是标准的Unix Berkeley sockets API 我知道我可以实现一个应用层ACK,但如果TCP的ACK能够很好地实现这一目的,我宁愿不这样做。AFAIK没有办法 而且,它也不可靠,ACK只意味着内核收到了数据,同时客户端或其机器可能已经崩溃。您可能认为客户机收到了数据,但实际上它从未处理过数据。不幸的是,标准API没有保留任何适当的

有没有办法让send()等待所有已发送的数据都已确认(如果已达到确认超时,则返回-1),或者有其他机制在发送()之后但在执行其他操作之前等待确认

我使用的是标准的Unix Berkeley sockets API

我知道我可以实现一个应用层ACK,但如果TCP的ACK能够很好地实现这一目的,我宁愿不这样做。

AFAIK没有办法


而且,它也不可靠,ACK只意味着内核收到了数据,同时客户端或其机器可能已经崩溃。您可能认为客户机收到了数据,但实际上它从未处理过数据。

不幸的是,标准API没有保留任何适当的方法来处理数据。有一种方法可以查询当前的TCP发送窗口大小/使用情况,但遗憾的是,它可能无法通过标准方式进行查询


当然,要达到你想要的目标,还有一些棘手的方法。例如,在Windows上可以创建一个网络过滤器驱动程序来监控数据包级别的流量。

我似乎找到了一个解决方案。至少在Linux上,如果将SO_SNDBUF的值设置为0,它似乎会等待每个事务,然后再允许下一次传输。虽然它会立即返回,但在前一次发送完成之前,它不会继续允许另一次发送成功。我还没有尝试使用select(…)来确定数据是否已发送


这可以在我的Linux 3.8内核上运行,我相信它可以在其他地方运行。

您可以为send()编写一个包装器。我在另一篇文章中回答了一个类似的问题。

你错了,TCP ACK不能达到这个目的。它告诉发送方的内核,接收方的内核得到的是字节,而不是目标应用程序(它甚至可能不会从套接字读取任何内容)。在你开始抛出诸如“TCP ACK”之类的词之前,你可能想费心去理解ACK是如何实现的以及它的含义。这是不准确的。ack不是来自本地内核,而是来自Nikolai上面提到的远程端的内核代码。因此,可以保证数据包到达远程端点,但不一定是远程用户应用程序读取了。@TJD:我说的是远程内核,我认为这很明显。@yi_H,不清楚,因为你说“客户端或其机器可能崩溃了”。我不清楚你的意思是客户端机器可能在内核确认后崩溃,但在客户端应用读取数据之前崩溃。正确答案和TCP的一个误解部分。对于每个请求,大多数应用程序都需要有应用程序级响应。ACK结构根本没有帮助,因为它是远程内核的接收。并且您应该更新您的响应,使其明显地成为您想要的远程内核。