TCP在网络协议(网络协议见这篇文章)中的重要性就相当于女朋友对于程序员的重要一样,这么说你应该知道有多重要了吧。

1. 三次握手

TCP在进行数据的传输之前必须先建立连接,建立之后才能进行数据的传输,那么所谓的建立连接是怎么回事呢?来看下其三次握手。

  1. 客户端发送SYNseq序列号,SYN为标识位,意思为请求同步,seq是此次包的序列号,序列号是单调递增的,作用是保证传输的可靠性,在丢包的时候能确定丢的是哪个包。

  2. 服务端收到消息之后,发送确认的信息,包括标识位SYN和ACK(表确认作用)、确认信息ack=客户端发送的seq+1,seq=自己的seq。seq和ack的确认机制知道确认的是哪个包。

  3. 客户端收到服务端的确认消息(也是请求同步的信息)之后,回复其同步消息,发送ACK=1和ack=服务端的seq+1还有自己的seq(值为第一次的seq+1,要单调递增),此时客户端这边的连接已经完成了。

  4. 服务端接收到客户端的消息之后,服务端这边的连接也完成,至此三次握手圆满结束,接下来就可以传输数据了。

三次握手的流程并不复杂,概括就是:客户端向服务端发送同步请求,服务端确认并向客户端发送同步请求,客户端确认,连接完成。

但是在这简单的流程中有几个问题需要思考:

  • 为什么需要三次握手?

  • 服务端有超时重传机制吗?确认包发送之后一段时间没收到响应会重发吗,还是等待客户端重发包。

  • 客户端收到服务端的确认消息之后能发送数据吗,即第二次握手完成的时候客户端能向服务端发送数据吗?

上面这些问题是不是除了第一个其他的都没想过?你可能会说,"那肯定啊,谁没事去想这玩意,我学TCP都是为了面试的时候能够把三次握手四次挥手说出来。"

哼!对于这种想法,我只能说:

 不过如果想造火箭,自己总不能是一颗汽车的轮子吧(布加迪威龙除外),所以必要的思考很重要。那来看看这几个问题

  • 为什么要三次握手?

    答:因为四这个数字不吉利。

     开个玩笑,麻烦把砖头收一收。首先我们得理解TCP是双方的连接,也就是说只有确定客户端和服务端的发送和接收都是没问题的这个连接才算完成。那来看下,第一次握手略过,第二次握手也就是客户端接收到服务端的确认消息时,这里证明了两个问题:

    1. 服务端的确认消息中的ack是自己的seq+1,说明服务端收到了自己刚才发的包并且能够明白。
    2. 自己收到确认消息说明服务端的发送端正常,自己的接收端正常。

     到第二次握手这里已经证明了三个所需条件:客户端的发送和接收正常、服务端的发送正常。还少一个服务端的接收,所以客户端要再发一次给服务端的确认包,让服务端也知道其发送和接收是正常的,所以总共是三次。

  • 服务端有超时重传机制吗?

     有的,如刚才所说,TCP是双端的协议,服务端是接收方也是发送方,所以是有超时重传的机制。比如说第三次握手客户端向服务端发送消息时由于网络原因丢包了,那么服务端一段时间后没收到消息就会重发。

  • 客户端收到服务端的确认消息之后能发送数据吗?

     意思就是说,在第二次握手完成后,客户端能不能向服务端发送数据。在回答这个问题之前,我先问一个问题,这时候客户端这边已经确认发送和接收没问题了,现在不能发,什么时候能发呢?所以是可以的,就算丢包也有确认应答和重发机制来保证。

三次握手结束之后,就可以进行数据的传输,这里有长连接短连接之分。可能放在这里比较陌生,但是另一个协议——HTTP的长连接和短连接应该都知道了,其本质就是TCP的长连接和短连接,而且作用是一样的,短连接在发送一次数据后就进行关闭,长连接则保持直到主动选择关闭分开。

说到分开,让我不由得想起那一年四月,夕阳淌在她的脸上,她用纤细的手指挽起了耳边的秀发,转过头对我说:"我们之间已经没有什么能给对方的了,总要一个人先开口,就像TCP'四次挥手'一样!"

醒醒,程序猿哪里有女朋友。

2. 四次挥手

 不知道怎么开头,先给大家看个宝贝吧。

 看了这张图都是字母,即便你告诉我这就是四次挥手,但这就像JOJO一样,一开始我是难以接受的。没有关系,鲁迅说过,"四次挥手比起机械的记忆,尝试去理解带来的性价比可能要高得多。"

我们一开始也说过,TCP是双方的协议,所以双方要有沟通,这样才能正确的关闭通道。而TCP的沟通,是这样的:

客户端:"我这边数据发完了,我要把我这边的发送通道关了,你看下你那边有没有什么问题。"

服务端:"嗯,我数据接收完了,你关吧,我把我这边的接收通道也关了。"

okay,这样客户端关闭了发送通道,服务端关闭了接收通道(注意,只能由发送通道发起聊天)。过了一段时间后,服务端这边的数据也都传输完了,他也想关闭了。

服务端:"我这边的数据也发完了,我这边把发送通道关了就下班了,你还有什么问题吗?"

客户端:"我这边也接收完了,你关吧,我也把这边的接收通道关了。等下下班后一起去修车吗?"

此时客户端还不能直接关完走人,因为他不知道修车地址啊(可恶)。说错了,是他担心服务端没收到他的消息,那需要等他个2MSL吧,如果服务端真的没收到会重新发信息过来的,到时候我再发一次就行。

到这里再回过头来看上面那张图。emem,是不是完全搞懂了。

(不理解再慢慢看看)个人觉得图中最重要的应该是TIME_WAIT状态,以及为什么要等2MSL,顺便说下MSL是报文单位,不想懂可以理解为另一种意义的秒。

所以以后再被问为什么要四次挥手?你就说为了一起修车(不是)。

3. TCP是如何保证可靠性的

 当我们被问到TCP和UDP的区别时,我们总会回答:"TCP是可靠的,而UDP是不可靠的。"但TCP为什么是可靠的,是怎么保证其可靠性的可能就没那么多人知道了。

  1. 校验和
  2. 序号和确认应答:
  3. 超时重传
  4. TCP不处理重复的包
  5. ARQ协议
  6. 流量控制
  7. 拥塞控制

 有了上面这些,安全、稳定全部搞定。

 你问这些是什么?

  • 校验和

     将头部和数据通过一个算法得到一个结果,这个结果就是校验和。校验和是防止包在传输的过程中被修改,接收端接收到包也会通过特定的算法来检测校验和是否能对上。

  • 序号和确认应答

     这在上方三次握手的时候也有涉及到,意思就是在发送方每次发送的包都是有序号的,如果包丢了,就要重新发下这个序号对应的包,而确认应答机制可以做到让发送端知道该重发的是哪个包。

     如上图,在传输的过程中,如果中途丢了一个包,例如上图的11-20的包,那么接收方就会不断的确认1-10的包,即便收到21-30的包,发送方收到三次这样的确认之后便判定包已丢失进行重发。

  • 超时重传

     这就没什么好说的,无论是服务端还是客户端在发送之后都会启动一个定时器,一段时间之后没收到确认定时器就会触发重发。

  • TCP不处理重复的包

     假设现在网络很慢,客户端发了消息之后一直没收到回复,就会重发,两次或者更多次,而且发的是同一个序号的包,那么这时服务端可能先收到一个包,进行处理后发送确认消息,之后又收到了同一个序号的包,此时便不做处理,直接丢弃,对于后面来的相同序号的包也执行相同的操作。

  • 连续ARQ协议

     TCP采用的是连续ARQ协议,大致的意思就是说,有数据不马上发,等待凑齐一定数量或者到了最大等待时间再发,凑齐一定的数量称为一组,而连续ARQ协议就是说不用等待确认消息再发下一组,可以连续发多组。(ARQ协议还有另外一种,有兴趣的可以自己了解下)

  • 流量控制

     在介绍流量控制之前,先提出一个问题:服务端有没有可能出现接收不过来的情况?肯定有,不然我接下来的内容怎么写。

     那么如果出现这样的情况,会有怎么样的后果呢?

     服务端处理不过来,给客户端的响应就会变慢,而客户端收不到响应触发超时重传,哦吼,服务端本来就忙不过来,你还一直施加压力,这不是让服务端往死路逼嘛。

     而流量控制,就是为了解决这种问题的。那么流量控制究竟做了什么呢?

     首先,发送方和接收方双发之间都维护了一个窗口,叫滑动窗口。接收方的窗口规定了还能接收多少数据,而发送方的窗口则规定了还能发送多少数据。接收方在回复确认信息的时候会将其能接收的大小发给发送方,发送方的窗口大小则取最小值Math.min{接收窗口大小,网络窗口大小(下个节点讲)}。如果接收窗口的大小为0,那么发送方将不再传输数据,而是采用发送探测包的形式检测是否能继续发送数据。

  • 拥塞控制

     假设一个场景:

     客户端发出了一个包,由于网络原因,导致了重发,但还是得不到响应,所以就不断的重发,在这停住,然后把视野抽出来,看到有几亿个客户端如此,继续放送,现在会发生什么呢?

     原本网络由于某些原因可能只有一点堵塞,但是由于n个客户端进行了多次的重发操作,导致一下子就拥堵了起来,拥堵又会导致更多的客户端超时而重发,从而进入一个恶性循环,这,自然是不行的。

     那咋办呢?还能咋办,遇事不决,限流解决。限流要限多少呢?无论定多少都感觉会错,那从1开始逐渐逐渐往上升,总能有一个是对的吧?好想法!!!于是便有了慢启动算法,见下图。

     (此图片来源网络,若有侵权联系我删除)

    首先,发送方不是一下子发送所有数据,而是从小事做起,先发一个,如果正常那么发两倍,如此如此,直到到了一个阈值,如上图中的16,此时不能再两倍发了(因为再这样很容易就超时),所以+1发,就这样一直到到超时。如果发生了超时,阈值调整为发生超时时的一半,并且发送发从1开始按照上方的算法继续走。这就是慢启动算法。

     注意发送方能发的包大小还得看另一个参数——接收方的接收窗口大小,见上方流量控制的介绍。发送方的发送数据大小=min{接收方接收窗口,慢启动算法网络窗口},也就是两个的最小值。


     有了上面这些,还有谁能质疑TCP的可靠性呢?

如果觉得文章对你有帮忙,希望关注没事。[双手合十]

本文为博客园文章,点此跳转

参考:

https://blog.csdn.net/sinat_36629696/article/details/80740678

https://www.cnblogs.com/taoshihan/p/11215289.html

https://www.cnblogs.com/zxiner/p/7203192.html

网络滴神,TCP!的更多相关文章

  1. C#网络编程之---TCP协议的同步通信(二)

    上一篇学习日记C#网络编程之--TCP协议(一)中以服务端接受客户端的请求连接结尾既然服务端已经与客户端建立了连接,那么沟通通道已经打通,载满数据的小火车就可以彼此传送和接收了.现在让我们来看看数据的 ...

  2. iOS网络协议 HTTP/TCP/IP浅析

    一.TCP/IP协议       话说两台电脑要通讯就必须遵守共同的规则,就好比两个人要沟通就必须使用共同的语言一样.一个只懂英语的人,和一个只懂中文的人由于没有共同的语言(规则)就没办法沟通.两台电 ...

  3. java网络编程之TCP通讯

    java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...

  4. 嵌入式linux的网络编程(1)--TCP/IP协议概述

    嵌入式linux的网络编程(1)--TCP/IP协议概述 1.OSI参考模型及TCP/IP参考模型 通信协议用于协调不同网络设备之间的信息交换,它们建立了设备之间互相识别的信息机制.大家一定都听说过著 ...

  5. 【网络协议】TCP交互数据流和数据流成块

    前言 建立在TCP协议上的应用层协议有非常多,如FTP.HTTP.Telnet等,这些协议依据数据传输的多少能够分为两类:交互数据类型和成块数据类型. 交互数据类型,如:Telnet,这类协议一般仅仅 ...

  6. 网络编程之TCP编程

    网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...

  7. 【安富莱原创开源应用第1期】花式玩转网络摄像头之TCP上位机软件实现,高端大气上档次,速度2MB/S,华丽丽的界面效果

    说明:1.例子是两年前做的,一直没有顾上整理出来,今天特地整理出来,开源出来给大家玩.2.上位机是emWin模拟器开发的,大家估计很难猜到,所以你会emWin话的,就可以轻松制作上位机.做些通信和控制 ...

  8. 网络协议 9 - TCP协议(下):聪明反被聪明误

    网络协议 1 - 概述 网络协议 2 - IP 是怎么来,又是怎么没的? 网络协议 3 - 从物理层到 MAC 层 网络协议 4 - 交换机与 VLAN:办公室太复杂,我要回学校 网络协议 5 - I ...

  9. 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系

    [Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...

随机推荐

  1. Html5中input新增的表单元素和属性介绍。

    input标签主要用于Web表单的创建交互,以便接受来自用户的数据. 我们通过更改type属性的值,来实现不同的输入类型.在以前的写法中表单元素必须放在form元素所包含的里面,而在html5中,我们 ...

  2. Traffic Real Time Query System,题解

    题目链接 题意: 问从一条边到另一条边的必经点. 分析: 首先,问必经点,当然是要点双缩点(圆方树)啦,关键是把边映射到哪一点上,其实直接放在某联通分量的方点上就行,但是这个点并不好找,所以我们考虑一 ...

  3. 洛谷CF1292A NEKO's Maze Game,还是思维。。。

    题目直接找链接 题意: 有一个2*n大的平面,有的格子不能走,有的格子可以走,最初状态所有格子都可以走,有q个操作,每个操作都把某个格子变化一下:能走变不能走,不能走变能走,输出每次操作之后能否从1, ...

  4. 钉钉内置的浏览器怎么改变title

    在我项目的开发过程当中,遇到过在钉钉打开的vue写的h5页面,通过在路由切换的时候通过全局的路由钩子函数改变 document.title 的内容失效的问题. const routes = [ { p ...

  5. java 数据结构(二):java常用类 二 StringBuffer、StringBuilder

    1.String.StringBuffer.StringBuilder三者的对比String:不可变的字符序列:底层使用char[]存储StringBuffer:可变的字符序列:线程安全的,效率低:底 ...

  6. Python之爬虫(十六) Scrapy框架中选择器的用法

    Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分Xpath是专门在XML文件中选择节点的语言,也可以用在HTM ...

  7. Django框架09 /ajax、crsf、settings导入

    Django框架09 /ajax.crsf.settings导入 目录 Django框架09 /ajax.crsf.settings导入 1. ajax概述 2. ajax应用 3. ajax上传文件 ...

  8. PowerShell创建参考窗口

    背景 平常我们经常遇到这样一个问题,在使用一个窗口工作时常常需要参考其他窗口的文字或图片,此时就需要频繁切换窗口:或者是看视频时需要参考前面进度的画面:或者是阅读或写文档时需要参考其他位置的文字,这时 ...

  9. bzoj1745[Usaco2005 oct]Flying Right 飞行航班*

    bzoj1745[Usaco2005 oct]Flying Right 飞行航班 题意: n个农场,有k群牛要从一个农场到另一个农场(每群由一只或几只奶牛组成)飞机白天从农场1到农场n,晚上从农场n到 ...

  10. js dom演示

    <body> <div id="div1"> <p name="p1">p1内容</p> <p name= ...