首先,咱们先来熟悉下经典的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. 2019.11.18【每天学点SAP小知识】Day4 - ABAP 7.40新语法 FOR

    "今天学习一下FOR的语法,常用的2个语法. FOR wa|<fs> IN itab [INDEX INTO idx] [cond] "FOR i = … [THEN ...

  2. 虚拟环境mkvirtualenv

    python虚拟环境mkvirtualenv使用   安装virtualenvwrapper  pip install virtualenvwrapper   修改默认虚拟环境目录: 环境变量中新建: ...

  3. 利用python列出当前目录下的所有文件

    问题 当一个目录下有很多文件夹或者文件,我们想分析各个文件的名字,这时就可以写一个函数,列出当前目录下所有文件名字. 代码 src_dir = r'./' # 源文件目录地址 def list_all ...

  4. ScrollView设置了ContentSize高度为0,仍然能滑动的问题

    你有没有遇到过这样的情况: 对于ScrollView的不能上下滑动,设置了以下代码: _scrollViewTitle=[[UIScrollView alloc]initWithFrame:CGRec ...

  5. "首页添加至购物车,TabBar显示购物车的数量"实现

    今天学习别人的项目源码的时候,看到这样的一种实现功能:首页添加至购物车,TabBar显示购物车的数量....想到以前没有做过,这里学习了,记录一下: 实现的效果图如下: 当点击首页添加至购物的操作的时 ...

  6. Git 常用命令大全-转载

    一. Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态 git commit 提交 git branch -a 查看所有的分支git branch -r ...

  7. 应用安全 - 工具|平台 - Elasticsearch- 漏洞 - 汇总

    未授权访问 (1)/_cat/indices #Index个数查询 (2)/_mapping?pretty=true #type个数查询 (3)根据Index和type查询表数据 (4)/_river ...

  8. TCP协议基础(一)

    TCP为应用层提供的服务 提供进程和进程之间的通信 答: 怎么区分服务目的主机上的哪个进程呢? 通过提供端口号(well-known port), 如Telnet 23,DNS 53, HTTP 80 ...

  9. python基础之编码

    ascci:字母.数字.特色字符,1个字节-8位Unicode:两个字节-16位,升级版四个字节-32位uft-8:最少一个字节-8位,英文字母-1个字节-8位,欧洲-2个字节-16位,中文-3个字节 ...

  10. filebeat的层次架构图和配置部署 -- 不错的文档 - elasticsearch 性能调优 + Filebeat配置

    1.fielbeat的组件架构-看出层次感 2.工作流程:每个harvester读取新的内容一个日志文件,新的日志数据发送到spooler(后台处理程序),它汇集的事件和聚合数据发送到你已经配置了Fi ...