首先,咱们先来熟悉下经典的tcp/ip模型。

tcp/ip 模型为了方便使用,将osi七层模型划分成了四层,分别为网络接口层,网络层,传输层,应用层。

他们作用分别为:

1)网络接口层:主要作用是将ip地址和计算机的物理地址互相绑定,并实现二进制流和计算机硬件的高低电位的转换。
2)网络层:主要作用是通过ip地址将两台物理机链接起来,实现ip数据包的传输;
3)传输层:使源端主机和目标端主机上的对等实体可以进行会话。在传输层定义了两种服务质量不同的协议。即:传输控制协议TCP(transmission control protocol)和用户数据报协议UDP(user datagram protocol)。;
4)应用层:负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP、FTP等。

今天咱们主要来看下tcp模型中主要的tcp协议。

计算机通信中,要想实现可靠的网络通信,tcp协议是必不可少的一环。那么tcp协议是如何实现可靠通信的呢?这就首先要从经典的三次握手谈起。

三次握手即客户端与服务器至少(网络超时的话会多于三个)要发送三个数据包来建立tcp连接。

第一次握手:客户端发送建立连接数据包,发送之后状态变成SYN_SENT,数据包内容里面SYN标志位为1以及一个随机的序列号seq,假设值为j。
第二次握手:服务器收到请求之后,发送数据包给客户端,服务器状态变为SYN_RECV,数据包内容包含标志位SYN和ACK,值都为1。确认序列号ack值为j+1,随机序列号seq,假设值为i。
第三次握手:客户端收到服务端的数据包,验证ACK和SYN为1后,发送一个确认数据包,客户端进入ESTABLISHED状态,数据包包括标志位ACK,值为1。确认序列号ack,值为i+1。序列号seq,值为j+1.

补充说明下:确认序列号ack表示的是下一次收到的包的seq,接收方通过seq和len来确认数据包是否有效,是丢弃数据包,还是放入正常数据包序列或者是放入失序数据包序列。

那么下面咱们来看下为啥tcp是三次握手,不是两次,一次或者四次。

第一次握手:

a发送一个数据包给b。如果只握一次手,就建立连接,显然是不可能的,a连b的真实性都不知道。

第二次握手:

b收到连接请求后,发送确认建立连接请求。如果两次握手就成功建立连接的话会出现一个问题:
a给b发送了一个请求连接包,由于网络原因,过了很久之后b才收到这个包,b收到之后,向a返回一个数据包。这个时候由于时间超时,a会丢掉这个数据包。如果是两次握手的话,这时候b状态为成功建立连接,会一直等待a传输数据。这样会导致服务器资源浪费。

第三次握手:

a收到b的确认连接请求后,验证数据正确后,再向a发送一个确认请求,b收到后验证数据是否正确。正确后即连接建立成功。

三次握手可以很好的避免网络超时导致的丢包情况,服务器和客户端都要分别收到正确的ACK之后才能表示连接建立,如果未收到,就会启用超时重传机制。当然如果网络确实比较差,导致连接无法建立,也不可能一直重传。操作系统中会有设置重传次数这个字段,以避免无效重转。

为啥不四次握手:

最开始本来是四次握手,四次握手的情形是服务器发送的SYN和ACK是分开发送的,所以是四次,后面给进行了优化,所以就成为了三次握手。

挥手。

当客户端和服务器通过三次握手建立了TCP连接以后,就可以进行数据通信了,通信完毕后,双方就可以断开连接了,断开连接就会涉及到咱们的四次挥手了。下面咱们来简单看下tcp的四次挥手。

第一次挥手:

client发送一个标志位FIN为1和一个seq为m的数据包;

第二次挥手:

server收到了client发送的FIN报文段,向client回一个ACK报文段,ack值为m+1,server告诉client,我“同意”你的关闭请求,这个时候client不能在发送数据,server不能再接收数据,server还能给client发送数据;

第三次挥手:

server向client发送FIN报文段,请求关闭连接,同时server进入LAST_ACK状态;

第四次挥手:

client收到server发送的FIN报文段,向server发送ACK报文段,然后client进入TIME_WAIT状态;server收到client的报文段以后,就关闭连接;此时,client等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,client也可以关闭连接了。

至于为啥是四次挥手,本质的原因是咱们的tcp连接是全双工的,在两个方向都需要关闭,所以两个方向都需要发送一个关闭请求和确认请求。

下面介绍下tcp可靠的一个重要机制,超时重传。

超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。三次握手,正常的数据传输,以及四次握手过程中只要出现超时情况,都会触发重传。

那么tcp是如何界定超时的呢,这时候又引出两个新东西。一个是RTT,另外个是RTO。感兴趣的同学可以下去了解,这里就不再详细介绍了。

总结:tcp协议是一个很复杂的协议,本篇文章由于篇幅原因只是简单的介绍了其中很小一个知识点,并没有很深层次的介绍tcp,如有更多疑惑,欢迎留言讨论。

参考博客:https://juejin.im/post/5b1e9c65f265da6e26099bf3

可靠的TCP连接为何是三次握手和四次挥手的更多相关文章

  1. TCP的基本概念三次握手,四次挥手

    TCP的特性 TCP提供一种面向连接的.可靠的字节流服务 在一个TCP连接中,仅有两方进行彼此通信.广播和多播不能用于TCP TCP使用校验和,确认和重传机制来保证可靠传输 TCP使用累积确认 TCP ...

  2. TCP协议中的三次握手和四次挥手(图解)【转】

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. [更新于2017.01.04 ]该部分内容配图有误,请大家见谅,正确的配图如下,错误配图也不删 ...

  3. tcp建立连接为什么需要三次握手和四次挥手

    前言 众所周知tcp传输层协议在建立连接的时候需要三次才能建立起一个真正的可靠连接,可是为什么是三次呢,不可以是两次,四次等等呢,可以自己思考一番,带着疑问可以看下文. 三次握手 在<计算机网络 ...

  4. 真的懂了:TCP协议中的三次握手和四次挥手(关闭连接时, 当收到对方的FIN报文时, 仅仅表示对方不在发送数据了, 但是还能接收数据, 己方也未必全部数据都发送对方了。相当于一开始还没接上话不要紧,后来接上话以后得让人把话讲完)

    一.TCP报文格式 下面是TCP报文格式图: (1) 序号, Seq(Sequence number), 占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2) 确 ...

  5. TCP常见的定时器三次握手与四次挥手

    1.TCP常见的定时器 在TCP协议中有的时候需要定期或者按照某个算法对某个事件进行触发,那么这个时候,TCP协议是使用定时器进行实现的.在TCP中,会有七种定时器: 建立连接定时器(connecti ...

  6. 网络编程简介(OSI七层协议,TCP协议原理,三次握手与四次挥手)

    目录 网络编程 软件开发架构 C/S架构 B/S架构 网络编程的发展史 互联网协议 1.物理连接层 2.数据链路层 3.网络层 4.传输层 5.应用层 三次握手四次挥手 三次握手建链接 数据传输 四次 ...

  7. python网络编程-TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  8. TCP协议中的三次握手和四次挥手(图解)

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  9. [转]TCP协议中的三次握手和四次挥手(图解)

    本文转自:http://blog.csdn.net/whuslei/article/details/6667471 建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来 ...

随机推荐

  1. 003-Spring4 扩展分析-spring类初始化@PostConstruct > InitializingBean > init-method、ApplicationContext、BeanPostProcessor、BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

    一.spring类初始化@PostConstruct > InitializingBean > init-method InitializingBean接口为bean提供了初始化方法的方式 ...

  2. SQLSERVER大批量数据快速导入Redis

    目的 把单表近5千万的某单个字段导入到Redis,作为一个list存储. 方案一: 使用sqlcmd工具(sqlserver自带),直接生成命令在Redis-cli中执行. 方案一. 使用sqlcmd ...

  3. Sass简单使用

    Sass是成熟.稳定.强大的CSS预处理器,而SCSS是Sass3版本当中引入的新语法特性,完全兼容CSS3的同时继承了Sass强大的动态功能. 特性概览 CSS书写代码规模较大的Web应用时,容易造 ...

  4. SQL Server 收集数据库死锁信息

    背景 我们在数据库出现阻塞及时邮件预警提醒中监控了数据库的阻塞情况,为了更好的维护数据库,特别是提升终端客户用户体验,我们要尽量避免在数据库中出现死锁的情况.我们知道收集死锁可以开启跟踪标志如1204 ...

  5. C基础知识(1):基本数据类型

    C的基本数据类型包括整型和浮点型,长度及精度信息如下: #include <stdio.h> #include <limits.h> #include <float.h& ...

  6. python django项目创建及前期准备(使用pycharm)

    一.创建django项目 1.打开pycharm软件 2.点击菜单栏 File-->New Project,弹出如下对话框,如下图设置 二.基本配置 1.静态文件目录配置(用于客户端访问后台服务 ...

  7. python多媒体文件抽取

    多文件抽取有:只获取url,或直接下载,下面是怎么将数据下载下来,并显示进度. 本节主要介绍urllib模块提供的urlretrieve()函数.urlretrieve()方法直接将远程数据下载到本地 ...

  8. 掌握Pod-Pod调度策略

    一 Pod生命周期管理 1.1 Pod生命周期 Pod在整个生命周期过程中被系统定义了如下各种状态. 状态值 描述 Pending API Server已经创建该Pod,且Pod内还有一个或多个容器的 ...

  9. Java 操作Word表格

    本文将对如何在Java程序中操作Word表格作进一步介绍.操作要点包括 如何在Word中创建嵌套表格. 对已有表格添加行或者列 复制已有表格中的指定行或者列 对跨页的表格可设置是否禁止跨页断行 创建表 ...

  10. PHP架构剖析

    一:PHP是什么 PHP("PHP: Hypertext Preprocessor",超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML中 ...