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 ...
随机推荐
- Day01 - Python 基础介绍
1 Python 简介 1.1 Python 的由来 Python的创始人:吉多·范罗苏姆(Guido van Rossum) 1989年,吉多·范罗苏姆为了在阿姆斯特丹打发圣诞节假期时间,开发的一个 ...
- CXF整合Spring开发WebService
刚开始学webservice时就听说了cxf,一直没有尝试过,这两天试了一下,还不错,总结如下: 要使用cxf当然是要先去apache下载cxf,下载完成之后,先要配置环境变量,有以下三步: 1.打开 ...
- Android 开发之动画详解
一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画 ...
- Oracle 根据业务创建新的用户
新的需求,创建一个用户,可以查询基表的数据,但是不能修改,同时自己也可以创建对象 1.创建用户第一种方式 详细常见,前提 表空间和临时表空间必须存在 格式: create user 用户名 ident ...
- C# FileSystemWatcher 监视磁盘文件变更
简化需求:有一个简化了的需求是这样的:有一个拍照程序在运行,一旦抓拍之后则将图片文件存储至某目录,然后图片要上传至远程服务器并update数据库. 原需求:原先的需求是这样的:有一台PDA扫码枪,一个 ...
- Python获取web页面信息
import sys, urllib2 # req = urllib2.Request(sys.argv[1]) req = urllib2.Request('http://www.sina.com. ...
- Browser Link: Failed to deserialize JSON in Browser Link call
问题 VS2013中调试程序发现,在浏览器控制台输出如下截图代码:
- (转)C#中Trim()、TrimStart()、TrimEnd()的用法 .
C#中Trim().TrimStart().TrimEnd()的用法: 这三个方法用于删除字符串头尾出现的某些字符.Trim()删除字符串头部及尾部出现的空格,删除的过程为从外到内,直到碰到一个非空格 ...
- Java文件操作二:File文件的方法
一.文件的判断方法 判断方法 .boolean canExecute()判断文件是否可执行 .boolean canRead()判断文件是否可读 .boolean canWrite() 判断文件是否可 ...
- iOS 使用GBK编码的hmacMD5算法
该方法是写在工具类中的,而不是写在NSString的类别中 方法的声明: /** * 使用hmac-md5加密 * * @param clearText 原文 * @param secret ...