1. 三次握手

  1. TCP为什么相较于UDP是可靠连接?

    可靠连接是指,待通信的两个实体,能够满足通信数据包的有序性、完整性以及可靠性。对于UDP来说, 它的连接过程不需要握手,忽略丢失的数据包,并且不需要维持通信双方在线(即服务器端不需要维持巨大的并发连接)。而TCP在传递数据之前,会经历三次握手来确保通信的两个实体均处于ESTANLISHED状态, 另外还采用校验和、序列号、确认应答、超时重传、拥塞控制、拥塞避免等控制方法,以此来确保数据的可靠传输。

  2. 三次握手的本质

    三次握手的本质在于确保通信双方收到彼此请求/接收通信的确认消息

    这里我们以电话拨号到通话为例,假设A给B通电话,那么其过程如下:

    A. 拨号,(请求与B通话)

    B. 拿起电话并接听,“喂!您哪位?”,(希望确认A的身份) 

    A. 收到对方询问身份, 并回复“我是A啊”,  (回传身份确认消息)

    B. 收到回复,并确认了A的身份, 开始尬聊

  3. 三次握手的过程

    

    第一次握手:客户端主动请求建立连接。 客户端发送连接请求报文段, 将SYN首部标志位置为1, Seq(Sequence Number)为X(由操作系统动态随机选取一个32位长(8字节)的系列号。随后客户端进入SYN_SEND状态,并等待服务器端的确认。

    第二次握手:服务器收到客户端SYN请求,并发送被动连接请求。服务器收到第一次握手过程中接收的SYN,需要向客户端发送一个确认号ACK(收到的Seq序列号长度自增1),此外,还需将被动请求连接请求发送给客户端,及SYN=1, 最后再从操作系统随机分配一个8字节长度的序列号用于填充Seq,将以上信息发送给客户端之后,服务器端便进入SYN_RECV状态。等待来自客户端的响应请求确认。

    第三次握手:客户端收到服务器的被动连接请求,并发送确认号。客户端收到SYN&Seq&ACK之后,发送确认请求,ACK为接收的Seq序列号自增1,Seq为接收的ACK确认号。至此TCP便完成了三次握手。

    

    - URG: 此标志表示TCP包的紧急指针域(有效,用来保证TCP连接不被中断,并且督促中间层设备要尽快处理这些数据。
    - ACK: 此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中。有两个取值: 0和1,为1的时候表示应答域有效,反之为0。
    - PSH: 这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队。
    - RST: 这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包。
    - SYN: 表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1,ACK=0。连接被响应的时候,SYN=1,ACK=1。这个标志的数据包经常被用来进行端口扫描。扫描者发送一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口。但是由于这种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全的主机将会强制要求一个连接严格的进行TCP的三次握手。
    - FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。
 

  4. 为什么是3次握手,而不是2次或者4次?

在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是
“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。
这两种不同的表述其实阐明的是同一个问题。
谢希仁版《计算机网络》中的例子是这样的,
“已失效的连接请求报文段”的产生在这样一种情况下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,
以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。
但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。
于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。
由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。
但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
采用“三次握手”的办法可以防止上述现象发生。
例如刚才那种情况,client不会向server的确认发出确认。
server由于收不到确认,就知道client并没有要求建立连接。”

  我们也可以假想一下,如果是两次握手,那么客户端向服务端发送请求连接SYN这是第一次握手服务器向客户端发送确认收到SYN的请求这是第二次握手,此时问题就来了,结果就是只要服务器发送一个确认报文给客户端,那么就代表连接建立了,但是网络信道是不可靠的,很容易碰到高时延的情况发生,假设一个来自客户端本就失效的连接报文(SYN)经过很长时间到达了服务器端(客户端早已断开连接),此时服务器按照流程返回一个确认号,便进入了ESTABLISHED状态,这样一来服务器状态与客户端状态便不一致了,假设有多个这样的情况发生,操作系统内存很容易崩溃。

  说完了两次,那么四次呢? 四次握手其实是可以的。其与三次握手的相同之处在于,必须收到彼此的对应请求报文的确认号才进入ESTABLISHED状态。但是,四次握手不必要,他将第二次握手的ACK与SYN分两次进行发送了,其结果就是连接速度效率低。

  因此采用建立TCP连接三次握手是必要的。

2.四次挥手

  1. 四次挥手过程

  

    四次挥手不存在Client及Server的说法, 因为客户端及服务器都能够主动关闭连接。

    第一次挥手:主动方主动提出关闭连接。当主动方发送断开连接请求(FIN=1, Seq=X)给被动方之后, 主动方由ESTABLISHED状态转为FIN-WAIT-1状态等待来自服务器的确认消息。

    第二次挥手:被动方收到来自主动方的FIN请求,被动方关闭应用层的应用程序,响应一个确认报文(ACK=x+1, Seq=y),并进入CLOSE-WAIT状态。

    第三次挥手:被动方发送被动断开连接请求给主动方。但此时可能出现应用程序有些TCP消息已经存在于被动方的发送队列中,这部分数据仍能参与传送,所以等到数据发送完毕之后,被动方才发送被动断开连接请求(FIN=1, Seq=m,ACK=x+1), 并等待主动方确认,进入LAST-ACK状态。

    第四次挥手:主动方接收到被动方发送来的被动断开连接请求, 主动方发送确认(ACK=m+1, seq=x+1),注意第四次挥手的Seq字段为第二次挥手的ACK字段的值。

  2. 为什么连接的时候是3次,握手就是四次呢?

    这是因为在第二次挥手的时候, 被动方接收到来自主动方的主动断开连接请求,随即进入CLOSE-WAIT状态,为什么会存在这一个状态呢?是因为TCP通信过程中,其发送窗口仍存在该应用程序待发送的数据报文,必须等待这些报文全部发送完毕之后,才能够发送被动断开连接请求。所以将FIN及ACK分两次进行。

  

  3. 为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

    (补充:2MSL为最大报文段生存时间,代表发送到接收的最大时间)网络信道是不可靠的,随时都有可能发生请求超时的情况,假设第四次握手时,主动方发送的ACK确认报文丢失或超时,那么被动方由于不能收到该确认报文, 它就会又发送一个第三次握手的被动断开连接报文(FIN=1........),此时在TIME_WAIT状态下,主动方收到被动方的FIN请求,便开始重传ACK报文给被动方。因此,TIME-WAIT的意义就在于出现确认报文丢包时,能够重传确认报文。

    

  

浅析TCP三次握手及四次挥手的更多相关文章

  1. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    .引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道“三次”和“四次”,但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方 ...

  2. [转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

    脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手   http://www.52im.net/thread-1729-1-1.html     1.引言 网络编程中TCP协议的三次握手和 ...

  3. TCP三次握手及四次挥手详细图解

    TCP三次握手及四次挥手详细图解 Andrew Huangbluedrum@163.com    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不 ...

  4. 用wireshark抓包分析TCP三次握手、四次挥手以及TCP实现可靠传输的机制

    关于TCP三次握手和四次挥手大家都在<计算机网络>课程里学过,还记得当时高超老师耐心地讲解.大学里我遇到的最好的老师大概就是这位了,虽然他只给我讲过<java程序设计>和< ...

  5. 应聘复习基础笔记1:网络编程之TCP与UDP的优缺点,TCP三次握手、四次挥手、传输窗口控制、存在问题

    重要性:必考 一.TCP与UDP的优缺点 ①TCP---传输控制协议,提供的是面向连接.可靠的字节流服务.当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供 ...

  6. 【HTTP协议】---TCP三次握手和四次挥手

    TCP三次握手和四次挥手 首先我们知道HTTP协议通常承载于TCP协议之上,HTTPS承载于TLS或SSL协议层之上 通过上面这张图我们能够知道.     在Http工作之前,Web浏览器通过网络和W ...

  7. 网络通信 --> TCP三次握手和四次挥手

    TCP三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 一.TCP报文格式 如下图: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发 ...

  8. TCP‘三次握手’和‘四次挥手’(通俗易懂)

      概述 我们都知道 TCP 是 可靠的数据传输协议,UDP是不可靠传输,那么TCP它是怎么保证可靠传输的呢?那我们就不得不提 TCP 的三次握手和四次挥手. 三次握手 下图为三次握手的流程图 下面通 ...

  9. 【转】TCP三次握手和四次挥手全过程及为什么要三次握手解答

    TCP三次握手和四次挥手的全过程   TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种表示: SYN(synchronous建立连接) ...

随机推荐

  1. 【转载】C#中string类使用Substring方法截取字符串

    在C#的字符串操作过程中,截取字符串是一种常见的字符串操作,可使用string类的Substring方法来完成字符串的截取操作,该方法支持设定截取的开始位置以及截取的字符串长度等参数,Substrin ...

  2. 如何打包ANE

    来源:http://blog.sina.com.cn/s/blog_6471e1bb01012aql.html 首先先说一下打包ANE必须的部件: 1.ActionScript扩展库SWC 2.本机扩 ...

  3. 将Centos7的yum配置为阿里云的镜像(完美解决yum下载太慢的问题)

    2017-02-17 16:02:30 张老湿 阅读数 13768     http://mirrors.aliyun.com/help/centos?spm=5176.bbsr150321.0.0. ...

  4. python3 提示sqlite模块不存在

    首先yum install sqlite-devel -y 然后重装下python3(一定要重装)# cd Python-3.4.2# ./configure --prefix=/usr/local/ ...

  5. UTF-8 中文编码范围

    主流的匹配字符有两种 [\u4e00-\u9fa5]和[\u2E80-\u9FFF],后者范围更广,包括了日韩地区的汉字 import re pattern = re.compile("[\ ...

  6. Computer Vision_33_SIFT: A novel point-matching algorithm based on fast sample consensus for image registration——2015

    此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...

  7. Redhat下Oracle 12c单节点安装

    操作系统:Redhat6.7 64位[root@Oracle12CDB ~]# more /etc/redhat-release Red Hat Enterprise Linux Server rel ...

  8. 【转】TCP报文格式定义详解

    TCP报文是TCP层传输的数据单元,也叫报文段. 1.端口号:用来标识同一台计算机的不同的应用进程. 1)源端口:源端口和IP地址的作用是标识报文的返回地址. 2)目的端口:端口指明接收方计算机上的应 ...

  9. Python 网络爬虫的常用库汇总

    爬虫的编程语言有不少,但 Python 绝对是其中的主流之一.下面就为大家介绍下 Python 在编写网络爬虫常常用到的一些库. 请求库:实现 HTTP 请求操作 urllib:一系列用于操作URL的 ...

  10. 【转】高性能网络编程1----accept建立连接

    最近在部门内做了个高性能网络编程的培训,近日整理了下PPT,欲写成一系列文章从应用角度谈谈它. 编写服务器时,许多程序员习惯于使用高层次的组件.中间件(例如OO(面向对象)层层封装过的开源组件),相比 ...