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连接建立和关闭中的疑难点的更多相关文章

  1. TCP连接建立与关闭

    http://hi.baidu.com/psorqkxcsfbbghd/item/70f3bd91943b9248f14215cd TCP连接建立与关闭 TCP 是一个面向连接的协议,无论哪一方向另一 ...

  2. 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...

  3. TCP连接建立和终止小结

    TCP连接建立(三次握手) 如图: 请求端发送一个SYN到服务器的相应端口,以及初始序号ISN 服务器发送包含服务器的初始序号的SYN作为应答,同时确认序号设置为客户的ISN+1 客户将确认序号设置为 ...

  4. 动手学习TCP:TCP连接建立与终止

    TCP是一个面向连接的协议,任何一方在发送数据之前,都必须先在双方之间建立一条连接.所以,本文就主要看看TCP连接的建立和终止. 在开始介绍TCP连接之前,先来看看TCP数据包的首部,首部里面有很多重 ...

  5. 《TCP/IP详解 卷一》读书笔记-----TCP连接建立

    1.在每个TCP报文段中,头部的flag字段里的SYN,FIN,RST,PSH可以多个有效,并没有限定为必须只有一个 2.TCP连接建立过程: 1)客户端发送一个SYN报文段,其中包含了客户端要传送的 ...

  6. TCP 连接建立和断开,以及状态转换

    1. TCP报文结构 TCP是一种可靠.面向连接.全双工的传输层协议,其报文格式如下所示:      源端口.目的端口:16位长.标识出远端和本地的端口号.     顺序号:32位长.表明了发送的数据 ...

  7. TCP连接建立与终止,及状态转换

    TCP连接建立 三路握手 三路握手发生在客户端发起connect请求到服务端accept返回中,在三路握手发生前,服务端必须准备好接受外来连接,这通常通过服务端调用 (socket.bind.list ...

  8. 浅谈TCP/IP网络编程中socket的行为

    我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: 1. TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) 2. Socket I/O系统 ...

  9. RTSP RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议

    RTSP 编辑 RTSP(Real Time Streaming Protocol),RFC2326,实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetwo ...

随机推荐

  1. [Webpack 2] Grouping vendor files with the Webpack CommonsChunkPlugin

    Often, you have dependencies which you rarely change. In these cases, you can leverage the CommonsCh ...

  2. android83 Activity的生命周期,启动模式,返回时传递数据

    #Android四大组件 * Activity * BroadCastReceiver * Service * ContentProvider #Activity生命周期 * oncreate:Act ...

  3. REDIS 源码

    http://blog.csdn.net/chosen0ne https://github.com/chosen0ne/task-schedule-simulate

  4. LPC2378-Jlink 能下载程序,但是调试出现各种奇怪问题

    LPC2378-Jlink调试经验 1.Jlink(d版的没有关系)不能下载程序?     把下载速率设置到500Khz及以下的速率. 2.Jlink能在500Khz的速率下载程序,但是不能调试?添加 ...

  5. 基于 CoreText 实现的高性能 UITableView

    引起UITableView卡顿比较常见的原因有cell的层级过多.cell中有触发离屏渲染的代码(譬如:cornerRadius.maskToBounds 同时使用).像素是否对齐.是否使用UITab ...

  6. Android(java)学习笔记187:Android中操作XML数据(使用Pull解析器)

    1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...

  7. 用FlexSlider制作支付宝2013版幻灯片演示插件

    flexslider制作支付宝2013版幻灯片精美特效,一款非常不错的jQuery特效源码可在下面地址或去源码搜藏网下载适用浏览器:IE8.360.FireFox.Chrome.Safari.Oper ...

  8. 自己做的demo---宣告可以在java世界开始自由了

    package $interface; public interface ILeaveHome { public abstract int a(); public abstract int b(); ...

  9. SqlSugar常用查询实例-拉姆达表达式

    SqlSugar支持拉姆达表达式查询,匿名对象参数等,相对还是比较方便好用的. 一.查询列表: //查询列表 SqlSugarClient db = SugarContext.GetInstance( ...

  10. 简单登录案例(SharedPreferences存储账户信息)&联网请求图片并下载到SD卡(文件外部存储)

    新人刚学习Android两周,写一个随笔算是对两周学习成果的巩固,不足之处欢迎各位建议和完善. 这次写的是一个简单登录案例,大概功能如下: 注册的账户信息用SharedPreferences存储: 登 ...