TCP连接建立和关闭中的疑难点
TCP连接建立和关闭中的疑难点
作者:夏语岚 撰写日期:2011-10-29
近日在阅读《Unix网络编程》,以前在《计算机网络》课程中学到TCP,当时只是简单了解了TCP连接建立的三次握手和关闭时的四次握手。并没有对其中各个状态以及其中的疑问进行深究。以下仅仅是个人的学习笔记~~
疑问1:TCP建立连接时为什么要进行第三次握手?
疑问2:TCP关闭连接时为什么是四次握手?
疑问3:为什么主动关闭的一端会出现TIME_WAIT状态?
在解答以上疑问前,先给出TCP连接建立和关闭的状态及状态变迁图:

图1 TCP正常连接建立和终止所对应的状态

图2 TCP的状态变迁图
疑问1解答:
客户端调用connect进行主动打开,并发送SYN J(J为序列号,序号用来标识从客户端向服务端发送的数据字节流)到服务端。在第一次握手完成后,服务端会发送SYN K和ACK J+1(对客户SYN J 的确认)到客户端,服务端此时的状态为SYN_RECV,服务端会为此状态维护一个半连接队列。当服务端收到客户的确认包ACK时,会在半连接队列中删除该条目,服务端进入ESTABLISHED状态。若客户端在收到服务端的SYN K和ACK J+1后不再发送ACK K+1确认包,则会导致服务端未完成队列溢出,此时服务端会给Dos攻击有机可乘。
服务端受Dos攻击的一个重要因素是:服务端在发送完SYN+ACK包后会等待客户端的ACK包,如果在一定的等待时间内未收到,服务端会进行首次重传,等待一段时间仍未收到客户ACK包,会进行第二次重传,直到重传次数超过系统规定的最大值,系统将该连接信息从半连接队列中删除。如果系统删除的频率小于半连接状态的增长频率,服务端就无法正常提供服务。
如果是设计成两次握手,就有可能是被连接方第一次发出ack消息后,就处于成功建立连接的状态,但这条消息丢失了,主动连接方因为没有收到这个ack消息会认为建立连接失败,也许会放弃连接或启动新的连接,但被连接方会一直监听那个它误认为成功的连接。采用三次握手,前两次握手任何一次失败都会导致连接双方都处于未连接状态,第三次失败只会导致连接方处于成功状态,但做主动连接方,肯定会在连接不久后通过这个连接发送数据,这样就可以利用这个机制做进一步的容错。
疑问2解答:
TCP关闭连接时为什么是四次握手?这是由于tcp半关闭(harf-close)造成的(所谓的半关闭TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。例如在TCP关闭连接步骤2和步骤3之间可以有从执行被动关闭端到执行主动关闭端的数据流)。TCP连接是全双工(即连接的双方既可以接收数据也可以发送数据),因此每个方向必须单独地进行关闭。即一方发送一个FIN,另一方收到后发送一个ACK,这就是所谓的四次握手了。其实四次握手并非绝对的,只是一般而言。因为有时步骤1的FIN随数据一起发送,另外,执行被动关闭的一端在步骤2和3发出的ACK和FIN也可以合并成一个字节同时发送。
疑问3解答:
为什么主动关闭的一端会出现TIME_WAIT状态?
TIME_WAIT状态有两个存在的理由:
(1) 可靠地实现TCP全双工连接的终止;
(2) 允许老的重复分节在网络中消逝。
第一个理由可以通过假设关闭连接时最终的ACK丢失了来解释。服务器将重新发送它的最终那个FIN,因此客户必须维护状态信息,以允许它重新发送最终那个ACK。要是客户不维护状态信息,它将响应以一个RST(另外一种类型的TCP分节),该分节将被服务器解释成一个错误。如果TCP打算执行所有必要的工作以彻底终止某个连接上两个方向的数据流(即全双工关闭),那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。本例子也说明了为什么执行主动关闭的那一端是处于TIME_WAIT状态的那一端:因为可能不得不重传最终那个ACK的就是那一端。
为理解存在TIME_WAIT状态的第二个理由,我们假设在12.106.32.254的1500端口和206.168.112.219的21端口之间有一个TCP连接。我们关闭这个连接,过一段时间后在相同的IP地址和端口之间建立另一个连接。后一个连接称为前一个连接的化身(incarnation),因为它们的IP地址和端口号都相同。TCP必须防止来自某个连接的老的重复分组在该连接已终止后再现,从而被误解成属于同一连接的某个新的化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接发起新的化身。既然TIME_WAIT状态的持续时间是MSL(最长分节生命期maximum segment lifetime)的2倍,这就足以让某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃。通过实施这个规则,我们就能保证每成功建立一个TCP连接时,来自该连接先前化身的老的重复分组都已在网络中消逝了。
后记:TCP连接的三次握手有可能遭受拒绝服务攻击(SYN-Flooding) ,而且TCP连接关闭时的TIME_WAIT状态保持整个连接的做法似乎不是很好。 TCP的这两个缺点可以由SCTP来规避~感兴趣的读者可以参考阅读《Unix网络编程》第二章之SCTP关联的建立和终止。
TCP连接建立和关闭中的疑难点的更多相关文章
- TCP连接建立与关闭
http://hi.baidu.com/psorqkxcsfbbghd/item/70f3bd91943b9248f14215cd TCP连接建立与关闭 TCP 是一个面向连接的协议,无论哪一方向另一 ...
- 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...
- TCP连接建立和终止小结
TCP连接建立(三次握手) 如图: 请求端发送一个SYN到服务器的相应端口,以及初始序号ISN 服务器发送包含服务器的初始序号的SYN作为应答,同时确认序号设置为客户的ISN+1 客户将确认序号设置为 ...
- 动手学习TCP:TCP连接建立与终止
TCP是一个面向连接的协议,任何一方在发送数据之前,都必须先在双方之间建立一条连接.所以,本文就主要看看TCP连接的建立和终止. 在开始介绍TCP连接之前,先来看看TCP数据包的首部,首部里面有很多重 ...
- 《TCP/IP详解 卷一》读书笔记-----TCP连接建立
1.在每个TCP报文段中,头部的flag字段里的SYN,FIN,RST,PSH可以多个有效,并没有限定为必须只有一个 2.TCP连接建立过程: 1)客户端发送一个SYN报文段,其中包含了客户端要传送的 ...
- TCP 连接建立和断开,以及状态转换
1. TCP报文结构 TCP是一种可靠.面向连接.全双工的传输层协议,其报文格式如下所示: 源端口.目的端口:16位长.标识出远端和本地的端口号. 顺序号:32位长.表明了发送的数据 ...
- TCP连接建立与终止,及状态转换
TCP连接建立 三路握手 三路握手发生在客户端发起connect请求到服务端accept返回中,在三路握手发生前,服务端必须准备好接受外来连接,这通常通过服务端调用 (socket.bind.list ...
- 浅谈TCP/IP网络编程中socket的行为
我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: 1. TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) 2. Socket I/O系统 ...
- RTSP RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议
RTSP 编辑 RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetwo ...
随机推荐
- [D3] 10. Creating Axes with D3
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- android 62 手机存储目录的划分
android下应用程序的路径和javase不同,应用程序的数据要保存自己的文件夹里面 > > getFileDir(); 获取自己的文件夹 /data/data/包名(应用程序的名字)/ ...
- java -Xmx3550m -Xms3550m -Xmn2g -Xss128k
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k1.-Xmx3550m:设置JVM最大可用内存为3550M.2.-Xms3550m:设置JVM促使内存为3550m.此值 ...
- Java泛型方法定义及泛型类型推断
泛型的推断 @Test public void test3(){ //类型推断时使用两个类型的最小公倍数 int x1 = add(3,4); Number x2 = add(3.5,4); Obje ...
- ASP.NET中如何实现负载均衡
ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一,做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同 ...
- Linq扩展方法之Aggregate 对序列应用累加器函数
Linq扩展方法之Aggregate 对序列应用累加器函数; 函数模板:// 函数名:对序列应用累加器函数. // Parameters:参数要求 // source:要聚合的 System.Col ...
- LAMP网站架构方案分析
本文引自:http://www.williamlong.info/archives/1908.html LAMP(Linux-Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框 ...
- 深入探讨C#中Socket一次性搞定消息发送
转载自:http://tech.chinaunix.net/a2010/0909/1101/000001101396.shtml [IT168 技术文档]最近浏览了几篇有关Socket发送消息 ...
- .NET3.5中的高性能 Socket API
转载:http://www.cnblogs.com/TianFang/archive/2007/11/09/954730.html 在 .NET Framework 2.0 版本中,System.Ne ...
- ASP.NET Web API 通过参数控制返回类型(JSON|XML)
一个很实用的技巧,可以在访问web api服务的时候指定返回数据的格式类型,比如 json 或者 xml. 因为 web api 默认返回的是XML格式,但是现在json 比较流行,同时网上也有其他的 ...