在计算机网络的学习中TCPi协议与Http协议是我们必须掌握的内容,其中Tcp协议属于传输层,而Http协议属于应用层,本博客主要讲解Tcp协议中的三次握手与四次挥手,关于Http协议感兴趣的可以参看我的博客:HTTP协议详解

一.三次握手:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,进入SYN_SEND状态,等待服务器确认; 

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器 进入SYN_RECV状态; 

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入 ESTABLISHED状态,完成三次握手。 

通过这样的三次握手,客户端与服务端建立起可靠的双工的连接,开始传送数据。 

三次握手的最主要目的是保证连接是双工的,可靠更多的是通过重传机制来保证的。

用图示表示如下:

那么为何需要三次握手呢?为何不是两次,即客户端给服务器端发送请求,服务器端应答请求做出回应。

最本质的原因是网络是一个复杂的环境,很可能存在网络环境较差的情况,即网络中可能存在某些信息滞留的情况,需要第三次握手(即客户端还要对服务器端的同步包做出确认才能建立连接)是为了防止已失效的连接请求报文段突然又传到了服务器端。现在我们考虑两种情况:

已失效的报文段:

第一种情况:已失效的报文段丢失了:A发出连接请求,但因为丢失了,故而不能收到B的确认。于是A重新发出请求,然后收到确认,建立连接,数据传输完毕后,释放连接,A发了2个,一个丢掉,一个到达,没有“已失效的报文段”

第二种情况:已失效的报文段没丢失,仅仅在网络中某个节点滞留了,延误到达,本来这是一个早已失效的报文段,但是在A发送第二个,并且得到B的回应,建立了连接以后,这个报文段竟然到达了,于是B就认为,A又发送了一个新的请求,于是发送确认报文段,同意建立连接,假若没有三次的握手,那么这个连接就建立起来了(有一个请求和一个回应),此时,A收到B的确认,但A知道自己并没有发送建立连接的请求,因为不会理睬B的这个确认,于是呢,A也不会发送任何数据,而B呢却以为新的连接建立了起来,一直等待A发送数据给自己,此时B的资源就被白白浪费了。但是采用三次握手的话,A就不发送确认,那么B由于收不到确认,也就知道并没有要求建立连接。

二.四次挥手

本质上是两个二次挥手过程。用图示表示如下:

FIN_WAIT_1::这个是已经建立连接之后,其中一方(通常为客户端)请求终止连接,等待对方的FIN报文。

FIN_WAIT-2状态:这就是著名的半关闭的状态了,服务器端收到连接释放报文段后就立即发送确认,然后就进入close-wait状态,当客户端收到服务器端的确认后就进入FIN_WAIT-2状态。这是在关闭连接时,客户端和服务器两次握手之后的状态。此时从客户端到服务器端的连接就释放了。即“半关闭”状态。即客户端不可以发送信息给服务器端,但是服务器端可以发送给客户端,即此时客户端只能接受数据,这也很好理解因为是客户端请求与服务器端断开连接,所以从客户端到服务器端的连接被释放。

此时,若服务器端没有数据报要发送给客户端了,其应用进程就通知TCP释放连接,然后发送给客户端连接释放报文段,此时服务器端等待确认进入LAST_ACK状态,该状态是为了等待对方的ACK报文,当收到ACK报文后,也即可以进入到CLOSED可用状态了



客户端发送确认后,进入time-wait,注意,此时TCP连接还没有释放掉,然后经过时间等待计时器设置的2MSL后,客户端才进入到close状态。

为什么要等待呢?

①、为了保证客户端发送的最后一个ACK报文段能够到达服务器端。即最后这个确认报文段很有可能丢失,那么B会超时重传,然后客户端再一次确认,同时启动2MSL计时器,如此下去。如果没有等待时间,发送完确认报文段就立即释放连接的话,服务器端就无法重传了(连接已被释放,任何数据都不能出传了),因而也就收不到确认,就无法按照步骤进入CLOSE状态,即必须收到确认才能close。

②、防止“已失效的连接请求报文段”出现在连接中。经过2MSL(报文段最大生存时间MSL(maximum segment lifetime)),那些在这个连接持续的时间内,产生的所有报文段就可以都从网络中消失。即在这个连接释放的过程中会有一些无效的报文段滞留在楼阁结点,但是呢,经过2MSL这些无效报文段就肯定可以发送到目的地,不会滞留在网络中。这样的话,在下一个连接中就不会出现上一个连接遗留下来的请求报文段了。

可以看出:服务器端结束TCP连接的时间比客户端早一点,因为服务器端收到确认就断开连接了,而客户端还得等待2MSL.

TCP协议三次握手与四次挥手详解的更多相关文章

  1. TCP协议“三次握手”与“四次挥手”详解(上)

    在使用TCP协议进行数据的传输之前,客户端与服务器端需要建立TCP Connection,即建立连接,之后两端才能进行数据的传输. 下面堆TCP连接“三次握手”的过程进行说明. 1.相关概念 首先,我 ...

  2. TCP协议“三次握手”与“四次挥手”详解(下)

    前面进行“三次握手”建立连接后,当客户端的数据发送完毕,它就会要求与服务器端断开连接,那么就要进行“四次挥手”进行连接的释放. 注意,此处所谓的“客户端”与“服务器端”,只是为了方便标识连接的双方,即 ...

  3. TCP的三次握手与四次挥手详解

    TCP的三次握手与四次挥手是TCP创建连接和关闭连接的核心流程,我们就从一个TCP结构图开始探究中的奥秘  序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序 ...

  4. TCP的三次握手和四次挥手详解

    相对于SOCKET开发者,TCP创建过程和链接折除过程是由TCP/IP协议栈自动创建的.因此开发者并不需要控制这个过程.但是对于理解TCP底层运作机制,相当有帮助. TCP报文格式 TCP的包如下: ...

  5. TCP三次握手与四次挥手详解

    目录 TCP三次握手与四次挥手详解 1.TCP报文格式 2.TCP三次握手 3.TCP四次挥手 4.为什么建立连接需要三次握手? 5.为什么断开连接需要四次挥手? 6.为什么TIME_WAIT状态还需 ...

  6. TCP/IP的三次握手与四次挥手详解

    TCP((Transmission Control Protocol)传输控制协议,是一个面向连接的协议.在运用此协议进行数据传输前都会进行连接的建立工作(三次握手):当数据传输完毕,连接的双方都会通 ...

  7. TCP三次握手与四次挥手详解(最全面)

    目录 TCP的三次握手与四次挥手 TCP报文段的首部格式 TCP的工作原理 TCP 的流量控制 TCP的拥塞控制 拥塞控制与流量控制的关系 拥塞控制所起的作用 慢开始和拥塞避免 慢开始算法的原理 三次 ...

  8. TCP协议三次握手与四次挥手通俗解析

    TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字 ...

  9. [ 转载 ] Tcp三次握手和四次挥手详解

    #TCP的报头: 源端口号:表示发送端端口号,字段长为16位.目标端口号:表示接收端口号,字段长为16位.序列号:表示发送数据的位置,字段长为32位.每发送一次数据,就累加一次该数据字节数的大小.注意 ...

随机推荐

  1. Android绘制文字时垂直居中

    canvas.drawText(String text, float x, float y, Paint paint); 是Android中绘制文本的方法,其中的x代表文字绘制时在X轴的起始点,而y是 ...

  2. I/O控制的主要功能

    主要功能: 1.  解释用户的I/O系统调用.将用户I/O系统调用转换为I/O控制模块认识的命令模式. 2.  设备驱动.根据得到的I/O命令,启动物理设备完成指定的I/O操作. 3.  中断处理.对 ...

  3. C++ 中私有继承、保护继承与公有继承

    区别 下面通过一个示例来介绍三种继承的区别. 定义一个基类(假设为一个快退休的富豪): class RichMan { public: RichMan(); ~RichMan(); int m_com ...

  4. 解决ansible首次连接host服务器需验证问题

    问题描述: [root@iZm5e79rtwsq2hm57teyk5Z ansible]# ansible aofeng -f 5 -m ping 47.93.18.191 | FAILED! =&g ...

  5. Redis Error:/var/redis/run/redis_6379.pid exists, process is already running or crashed

    命令service Redis start /var/redis/run/redis_6379.pid exists, process is already running or crashed 引起 ...

  6. jquery easyui combobox 高度自适应

    data-options="required:true,editable:false,panelHeight:'auto'"  加上panelHeight:'auto'即可 列合并 ...

  7. 关于return的一些了解

    写return是一种清晰的风格,可以防止一些意外的错误. 所以书上只说应该写,而不是必须写. 如果符合某个条件要退出的话,可以用return返回,否则可以不写这句代码的,当程序执行到"}&q ...

  8. Java 反射详解 转载

    java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ...

  9. node之querystring模块

    前言 querystring 模块提供了一些实用工具,用于解析与格式化 URL 查询字符串. 一.querystring.parse() 用于将一个查询字符串解析为JS 对象. const query ...

  10. jupyter notebook 更换主题的方法

    参考 https://github.com/dunovank/jupyter-themes install with pip # install jupyterthemes pip install j ...