为什么需要“三次握手”

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

为什么需要“四次挥手”
      那可能有人会有疑问,在tcp连接握手时为何ACK是和SYN一起发送,这里ACK却没有和FIN一起发送呢。原因是因为tcp是全双工模式,接收到FIN时意味将没有数据再发来,但是还是可以继续发送数据。

握手,挥手过程中各状态介绍:

3次握手过程状态: 
LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。 
SYN_SENT: 当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。(发送端)

SYN_RCVD: 这个状态与SYN_SENT遥想呼应这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个 ACK报文不予发送。因此这种状态时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。(服务器端)
ESTABLISHED:这个容易理解了,表示连接已经建立了。

4次挥手过程状态:(可参考下图)

 
FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。(主动方)
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。(主动方)
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)
CLOSING(比较少见): 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。(被动方)
LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)

CLOSED: 表示连接中断。

TCP的具体状态图可参考:

TCP为什么需要3次握手与4次挥手(转载)的更多相关文章

  1. 理论经典:TCP协议的3次握手与4次挥手过程详解

    1.前言 尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务.TCP提供一种面向连接的.可靠的字节流服务. 面向连接意味着两个使用TCP的应用(通常是一个客户和一 ...

  2. TCP协议的3次握手与4次挥手过程详解

    1.前言 尽管TCP和UDP都使用相同的网络层(IP),TCP却向应用层提供与UDP完全不同的服务.TCP提供一种面向连接的.可靠的字节流服务. 面向连接意味着两个使用TCP的应用(通常是一个客户和一 ...

  3. TCP连接的3次握手和4次挥手

    TCP连接的3次握手和4次挥手笔记 三次握手 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确 ...

  4. 转:TCP为什么要3次握手和4次挥手时等待2MSL、 TCP如何保证消息顺序以及可靠性到达

    关于tcp三次握手.四次挥手可以看这里:TCP与UDP的差别以及TCP三次握手.四次挥手 1.TCP为甚要3次握手? 在谢希仁著<计算机网络>第四版中讲“三次握手”的目的是“为了防止已失效 ...

  5. TCP/IP协议三次握手和四次挥手大白话解说

    前言 昨天晚上被一位师傅问到了TCP/IP的工作机制,心里很清楚三次握手,然而对于四次挥手却忘了,这是大学习里学过的,奋而翻阅书籍和网络对之前所学的做一个温顾,算是夯实自我吧. TCP(Transmi ...

  6. TCP 中的三次握手和四次挥手

    Table of Contents 前言 数据报头部 三次握手 SYN 攻击 四次挥手 半连接 TIME_WAIT 结语 参考链接 前言 TCP 中的三次握手和四次挥手应该是非常著名的两个问题了,一方 ...

  7. 详解TCP连接的“三次握手”与“四次挥手”(下)

    上文链接: 详解TCP连接的"三次握手"与"四次挥手"(上) 四.TCP的四次挥手(Four-Way Wavehand) 0.前言 对于"三次握手&q ...

  8. 白话解说TCP/IP协议三次握手和四次挥手

    白话解说TCP/IP协议三次握手和四次挥手 1.背景 和女朋友异地恋一年多,为了保持感情我提议每天晚上视频聊天一次. 从好上开始,到现在,一年多也算坚持下来了. 1.1.问题 有时候聊天的过程中,我的 ...

  9. TCP为什么做三次握手、四次挥手

    TCP 为什么做三次握手.四次挥手? TCP 是为了解决可靠传输出现的.为了实现可靠性,TCP 做了流量控制.拥塞控制,并且在建立.关闭连接前做些机制:三次握手.四次挥手. 三次握手是为了让客户端.服 ...

随机推荐

  1. xamarin android打开拍照

    xamarin android打开摄像头 Intent intentBrowser = new Intent("android.media.action.IMAGE_CAPTURE" ...

  2. ArcGIS API for JavaScript 4.2学习笔记[14] 弹窗的位置、为弹窗添加元素

    这一节我们来看看弹窗的位置和弹窗上能放什么. 先一句话总结: 位置:可以随便(点击时出现或者一直固定在某个位置),也可以指定位置 能放什么:四种,文字.媒体(图片等).表格.附件. [Part I 位 ...

  3. vue入坑总结

    1.Do not mount Vue to <html> or <body> - mount to normal elements instead. Vue2.x之后不推荐挂载 ...

  4. 深入学习rollup来进行打包

    深入学习rollup来进行打包 阅读目录 一:什么是Rollup? 二:如何使用Rollup来处理并打包JS文件? 三:设置Babel来使旧浏览器也支持ES6的代码 四:添加一个debug包来记录日志 ...

  5. MySql监控优化

    MySQL监控   MySQL服务器硬件和OS(操作系统)调优:   1.有足够的物理内存,能将整个InnoDB文件加载到内存里 —— 如果访问的文件在内存里,而不是在磁盘上,InnoDB会快很多. ...

  6. Django2.0中文文档

    title: Django2.0中文文档 tags: Python,Django,入沐三分 grammar_cjkRuby: true --- Django2.0版本已经发布了,我们先来看一个图片 从 ...

  7. 安装spark单机环境

    (假定已经装好的hadoop,不管你装没装好,反正我是装好了) 1 下载spark安装包 http://spark.apache.org/downloads.html 下载spark-1.6.1-bi ...

  8. 几种加密算法的java实现包括MD5、RSA、SHA256

    SHA加密: package com; import java.security.MessageDigest;import java.security.NoSuchAlgorithmException ...

  9. Windows内核中的内存管理

    内存管理的要点 内核内存是在虚拟地址空间的高2GB位置,且由所有进程所共享,进程进行切换时改变的只是进程的用户分区的内存 驱动程序就像一个特殊的DLL,这个DLL被加载到内核的地址空间中,Driver ...

  10. spring boot系列03--spring security (基于数据库)登录和权限控制(下)

    (接上篇) 后台 先说一下AuthConfig.java Spring Security的主要配置文件之一 AuthConfig 1 @Configuration 2 @EnableWebSecuri ...