TCP是一个可靠的协议。有时人们会说:"TCP能够保证它所发送数据的可靠传输。"这种说法尽管很常见,但却非常不恰当。
首先,只要稍微想一下就会知道这不可能是对的。比如,假设在数据传输的过程中将一台主机从网络上断开,TCP这侧不管做出何种努力,都无法获取其余 的数据。网络确实会中断,主机确实会崩溃,用户确实会在TCP连接仍然活跃的时候关机。这些事件或其他类似的事件都使得TCP无法将它从应用程序收到的数 据传送出去。
但更重要的是,TCP"确保可靠传输"这种说法会对不够谨慎的网络程序员产生微妙的影响。当然,没人真的会相信TCP有某种魔法总是可以将数据安全 地传送到其目的地。但是,相信TCP能够保证可靠传输会让人觉得没必要进行防御性编程,也没必要考虑对故障模式的处理,还是那句话,毕竟TCP可以确保可 靠传输。
可靠性--是什么,不是什么
在考虑TCP中可能出现的各种故障模式之前,要弄清楚TCP的可靠性意味着什么。如果TCP不能保证将提交给它的所有数据都传送出去,它又能保证什 么呢?第一个问题是向谁保证?图2-41显示,数据流从应用程序A通过它所在主机的TCP/IP栈向下传输,经过几台中间路由器,通过应用程序B所在主机 的TCP/IP栈向上传输,最后抵达应用程序B。一个TCP段离开应用程序A所在主机的TCP层时,会被封装到一个IP数据报中,传送给其对等实体主机。 它所走的路由可能要经过很多路由器,但如图2-41所示,这些路由器都没有TCP层,它们只是转发了IP数据报。
实际上,有些"路由器"可能是拥有完整TCP/IP协议栈的通用计算机,但在这种情况下,它们的路由功能也不涉及TCP或应用层。
我们知道IP是个不可靠的协议,那就应该很清楚,在数据传输路径上,第一个可以讨论确保可靠传输问题的地方就是应用程序B所在主机的TCP层。当一 个段抵达应用程序B所在主机的TCP层时,唯一可以确定的就是这个段已经到达了,但它可能损坏了,可能是重复的数据,可能是错序的,或者是由于其他一些原 因无法接受的。注意,发送端TCP无法对这些抵达接收端TCP的段做出任何保证。
但接收端TCP要向发送端TCP确认,也就是说它ACK的数据以及在此数据之前到达的所有数据在TCP层都已经正确收到了,发送端TCP可以安全地 删除这些数据的副本了。这并不意味着已经将数据传送,或者总是可以将数据传送给应用程序。比如,接收端主机可能在刚刚对数据进行了ACK,但应用程序还没 有将其读走之前,就崩溃了。这个问题值得进一步讨论:TCP向发送端提供的唯一一个数据接收通知就是这个ACK。发送端应用程序无法从TCP自身判断对等 实体应用程序是否真的收到数据了。稍后我们会说明,这是应用程序编写者要弄清楚的一种TCP故障模式。
另一个可以讨论确保可靠传输问题的地方是应用程序B。我们知道,无法保证应用程序A发送的所有数据都会到达。TCP能够向应用程序B保证的是所有到达的数据都是按序且未受损的。
前面已经提到过一种TCP故障模式了:TCP已经ACK了的数据实际上可能不会抵达目的应用程序。这是相当罕见的事情,即使发生这种事情,影响也不会太严重。重要的是网络程序员要知道这种可能性的存在,要对这种或其他所有故障模式可能带来的不良后果有所预防。要避免这样一种看法:TCP会做好一切准备,我们不需要为应用程序协议的健壮性操心。
前面讨论的故障模式有很明确的解决方案。对应用程序来说,明确地知道对等实体收到了某个特定的报文是非常重要的,其对等实体就必须将收到报文的信息 通知发送端。通常,这种确认信息都是隐式的。比如,如果客户端向服务器请求一些数据,服务器进行了响应,那么,这个响应就隐式地确认收到了原始请求。
一个更难解决的问题是如果服务器没有对收到的报文进行确认,客户端会怎么做?当然,这与特定的应用程序有很大的关系,很可能没有一个统一的解决方 案。但我们应该注意到,仅仅重发请求很可能无法解决问题:我们不想请求银行进行两次转账。数据库系统使用三阶段提交协议来处理这种类型的问 题,某些应用程序可能会使用类似的策略来确保操作"最多执行一次"。
TCP是一个端对端协议,也就是说它自己要在对等实体之间提供可靠的传输机制。但是,认识到"端点"位于对等的TCP层,而不是对等的应用程序中是非常重要的。要求进行端到端确认的应用程序必须自身提供此项功能(比如WCF实现的WS-RM)。
看看其他一些"常见的"故障模式。只要两个对等实体仍然连着,TCP就能保证将数据按序、无损坏地传送。只有连接中断时才会出现故障。什么类型的事件会造成这种中断呢?有三种情况可能引发这类问题:
(1) 永久或临时的网络中断;
(2) 对等的应用程序崩溃;
(3) 运行对等应用程序的主机崩溃。
我们会看到,在发送端应用程序中,这些事件会以不同的方式显现出来。
原文地址:http://www.cnblogs.com/lwzz/archive/2011/07/03/2096967.html