在RFC 793中,有一部分关于TCP段的确认:


当TCP传输包含数据的段时,它将副本放在
重传队列上并启动计时器收到
数据确认后,该段将从队列中删除。如果在计时器用尽之前未收到
确认,则将重新传输段


TCP的确认并不能保证数据已交付给最终用户,而不能保证接收方的TCP已经承担了责任。

/>
现在,这很有趣。在我们的NOC中,我们经常对网络与外部客户端网络之间的连接问题进行故障排除,并且每当我们在防火墙上嗅探流量并看到双向发送和接收的SYN和ACK位时,我们都假定已建立连接并且问题不存在。做网络。

但是,现在这个RFC让我开始思考-如果建立了TCP连接,但用户仍然遇到连接问题,我还应该检查(不设置Wireshark)该怎么办?

评论

该句子的含义仅是该句子的字面意思:网络驱动程序接收到数据(并确认接收)的事实并不能保证最终用户接收到数据。例如,Web服务器中可能存在错误。关于您的最后一个问题:弄清最终用户是否收到数据的唯一方法是打电话给他们,然后询问他们。

#1 楼

RFC的这一部分是关于将责任转移到操作系统或过程的下一阶段。从根本上讲,它与层的分离有关。


TCP的确认不能保证数据已交付给最终用户,而只是保证接收方的TCP承担了责任。这样做。


我一直这样考虑:


操作系统可能在发送ACK和到达客户端的数据之间崩溃。进程(此处的“客户端”是指操作系统的客户端,而不是“网络客户端”)
客户端进程可能有错误或崩溃,或者比处理传入数据的预期速度慢得多,或者实际上只是在非显而易见的情况下读取它
如果客户端正在向磁盘文件发送数据,则可能尚未写入或刷新文件
如果客户端正在通过TCP向前发送数据,远端TCP可能未传输数据,未收到ACK,或者远端进程成功使用了数据

所有的意思是这是一层3确认(“我听到了您的字节”)不是更高层的确认。考虑例如TCP ACK,下一跳邮件网关接受消息后的SMTP 250 OK,消息接收消息(例如,按照RFC 3798),消息打开的跟踪像素,来自PA的感谢信之间的区别,并回答“是的,我会做。”

另一个具体示例是打印机:


它必须在数据发送之前对ACK进行确认。知道它的末尾包含什么(可能是一个Postscript文件,其开始时包含的库大于TCP传输窗口)
它可能包含一个状态查询(“您有纸吗?”,显然可以执行)
它可能包含打印命令(“ please print this”,如果缺纸,它可能会失败)

我建议如果用户正在查看和发送ACK,但仍然遇到连接问题,那么拥塞,操作系统或应用程序问题的发生率要比与网络完全相关的问题高出几个数量级。

诊断我建议寻找重传,而不是专门的ACK。

评论


另一个项目符号:即使客户端进程运行良好,它可能仍未读取数据。

– Barmar
18/12/20在22:09

客户端进程(如果感到懒惰或不正常)可能根本不会在套接字上调用recv(),在这种情况下,接收到的数据将无限期地保留在TCP套接字的接收缓冲区中。

–杰里米·弗里斯纳(Jeremy Friesner)
18/12/21在6:04

都感谢双方,对其进行了更新,以表明客户端进程可能很慢,容易出错,变化无常。

– jonathanjo
18/12/21在11:51

您不能依靠ACK来确保应用程序处理了您的输入,您必须实现应用程序层ACK或Check。换一种说法。对于在客户端使用带有IP堆栈的TSN的工业控制网络,TCP ACK不足以保证过程变量被锁存。也就是说,您不能依靠TCP ACK来使系统处于安全或可维护的状态,您必须从应用程序层服务中确认,可以安全地将手伸入机器中。

–疯狂
18/12/21在19:06



#2 楼

从RFC的角度来看,“最终用户”是应用程序。不能保证应用程序可以获取数据,而不能保证TCP进程已接收到数据。

从您的NOC角度来看,网络正在运行,并且数据到达了最终主机。大概这就是您所关心的。

#3 楼

您可以用这种方式看到它。

您是M.Smith,想发送一封信给M.Toto(人员是应用程序层)。

要发送信,您去当地的邮局A,它将把信件发送给M.Toto本地邮局B(邮局是TCP层)。邮局B-B将向邮局A发送ACK。但是,不能保证这封信会到达M.Toto。邮局B和M.Toto之间可能发生任何事情。

这基本上就是RFC所说的。