TCP和UDP总结笔记

最近在准备实习面试,所以复习一些基本知识点,故做此笔记。
在这篇文章中,你将看到:
一.什么是TCP和UDP?
二.TCP和UDP的共同点以及特点是什么?适合用于什么场景。
三.TCP的三次握手,二次分手是什么?
四.TCP面向连接是如何面对计算机网络领域中的两个重要问题?
五.TCP是如何实现拥塞避免的?

1.什么是TCP和UDP?
在时候就不得不提计算机网络的五层协议啦,TCP和UDP就是在计算机网络中的第二层协议运输层的两个协议啦,而运输层基于下面的网络层的IP协议,是一个明显的端到端协议,IP以及再下面的链路层协议解决的主机与主机之间如何传输数据,而运输层协议更加关注的则是如何把传递到指定主机上的数据分发给指定的进程,也就是说,TCP和UDP需要关心的问题是如何进行进程间的通信,也就是端口绑定到那个进程, 运输层目的是实现逻辑通信,如下图所示:
这里写图片描述

2.TCP和UDP的共同点以及特点是什么?适合用于什么场景。
先总结性的说一说这两种连接的特点,TCP是面向连接的协议,而UDP是不面向连接的协议,UDP的目的是尽力的进行传输(只要能把数据传输过去,其他数据完整性、丢包问题我都不管啦。嘤嘤嘤!)但是这两个协议也有共同的地方。因为,TCP和UDP最起码都是运输层协议,都要支持进程间的通信,也就是要支持多路复用和多路分解。别听这两个名词特别的高大上,简单来说,多路复用是为了能将数据交给网络层的IP协议,也就是说将各个进程的数据进行整合,一定交给IP协议(发送方)。多路分解就更简单啦,我们收到了网络层的数据包,然后将一整个数据包根据TCP或者UDP的报头进程信息进行分解和进程分发。讲到这里,我相信两种协议需要哪些信息也就一目了然了,我想要知道我要把数据发给那个进程(那个端口),发给那个主机(IP),这是我们进行数据发送的最基本信息。同时,这也是我们最简单的UDP协议的报文信息,UDP的报文信息就是只有目的IP和目的端口(进程)以及长度和校验和,换句话说,如果不同主机或者不同进程发送相同主机和相同端口,UDP是无法进行识别的。
但是在实际应用当中,主机号(也就是IP,已经被网络层的IP协议锁确定了,所以我们只要端口就行了,也就是源端口号以及目的端口号)UDP只将数据进行传输以及做简单的差错检验,UDP的报文信息如下图所示:
这里写图片描述
效应码也很简单,只要将源端口号、目的端口号、长度进行相加(溢出回卷)取反码就得到检验和。那么,当发送数据成功的时候,如何信息没错,接收方将所有报文字段进行相加得到总和应该为1.当然,你如何想要考虑更多的安全问题,就要从信息安全的角度考虑,考虑认证、信息是否被篡改、信息是否被窃听等的加密问题,这显然不是我们这里所要考虑的。
同时,UDP的信息完整的前提则可以认为网络层的IP协议完全可信的情况下
而TCP协议是面向连接的,于是信息就更加丰富了,源端口号、源主机、目的主机、目的端口号,各种信息应有尽有。
说这么多,可以看多TCP适用于HTTP这种对信息完整性较高的应用。而UDP更加适用于网络流视频、通话这种容忍一定量的数据丢失,但即时性较强的情况。

3.TCP的三次握手、二次分手是什么?
老是听说在计网中相当著名的三次握手、二次分手,但三次握手、二次分手到底是什么呢?首先,先了解我们为什么要进行三次握手。正如我们之前所说的,TCP是面向连接的协议,面向连接,我们所要做的第一件事就是确认已经连接上了啊。这就需要三次握手啦。这里还是先抛一张三次握手的图出来,再进行讲解:
这里写图片描述
三次握手,我们当然分成三步来讲撒:
第一步:客户端设定SYN=1,并且指定开始的序列号为client_isn,第一步是为了客户机向服务器说明,我想进行连接的事实。
第二步:服务器成功收到了客户端的消息,为该TCP连接设置缓存和内存等数据,并将回应的序列号设置为client_isn+1,同时设定自己服务器的序列为server_isn。第二步的目的是服务器发布连接允许的信息。
第三步:客户端收到了允许连接的信息,将SYN置为0(这里可以说明SYN字段是为了TCP的三次握手连接而存在的),这里的ack回应包设置为server_isn+1,传回服务器,同时,客户端设置TCP缓存空间。
Done!
这三步都正常的时候,咱们的客户端和服务器的连接就正常而正确的完成了。
这里有几个延伸思考:
一.为什么是三次握手而不是二次握手?我这里初步想的是如果只有两步的话,服务器无法知道客户机何时才能将缓存设置完成,这样的连接是有一定风险。真正的原因,我留在这里,后来补上。
二.针对复杂的三次握手,有很多攻击针对于TCP连接的三次握手,SYN洪泛攻击就是针对于三次握手的一个攻击,通过大量只发送SYN的信息,不断耗尽缓存资源。当然,有攻击自然有防御,防御方案就是从seq上面着手。

二次分手的说明:
还是先上图,然后再说明:
这里写图片描述

天下没有不散的宴席。我们要结束TCP连接的时候,应该怎么样结束呢?肯定要发送一个结束报告喽。二次分手,那我们就分开讲两步:
1.客户端发送FIN=1的数据包申明自己要结束,并停止发送报文段,服务器返回一个ACK。第一步是针对客户端。
2.服务器返回一个ACK之后,再发送一个FIN字段=1,说明自己要结束,之后客户端返回一个ACK。第二步是针对服务器。
双方都申明结束之后,双方的TCP资源全都释放掉。
Over!

4.TCP面向连接是如何面对计算机网络领域中的两个重要问题?
为什么我们需要面向连接的协议呢?主要就是为了解决我们在计算机网络当中最关注的几个问题?这些问题都基于一个来源,我们的信道不可信(下层的数据不可信)。问题有二:1.信道的数据受损(数据错误)。2.数据丢失(包数据顺序错误)

好了,那么接下来看我们的TCP协议怎么解决这些问题的?
首先是数据错误问题:
1. 自然从我们的日常生活中进行延伸。我们打电话的时候,对于一个命令就会做出一个回应,“听到了”或者“没听到”,我们的TCP面对数据传输也会进行这样的,之后在进行重发,每当发送方发送一个信息,接收方接受到之后会回复一个ACK包,说明有没正确传输数据(利用检验和来确定数据是否正确)。但是ACK包万一也错了呢?这就要通过包的序号来解决这个问题,由于这里只针对数据错误,而不针对数据丢失的问题。我们只需要0-1的序号就够啦。如果收到同一个分组的两个ACK,则说明数据传输错误,进行重发。这样的过程,我们通过如下图的有限状态机来进行展示:
这里写图片描述

发送方

接收方

接收方

扫描二维码关注公众号,回复: 2656524 查看本文章

各种函数相关解释下哈:
rdt_rcv(revpkt):接收数据并存储在revpkt中
isACK(rcvpkt):收到正确应答
isNAK(rcvpkt):收到错误应答
corrupt(rcvpkt):收到信息错误
notcorrupt(rcvpkt):收到信息正确
udt_send(sndpkt):发送数据
make_pkt(ACK,checksum)进行应答
has_seq0(rcvpkt):查看数据是否是指定0序列

如果发生丢包怎么办:
发生丢包往往产生的结果是接收方长时间接收不到数据包,这时候就要做的是超时重传。
丢包以为着数据包不会达到,就像我们约会时候等人而言,如果太长时间等不到人,我们就要考虑重新问一次人在不在啦,这个的解决方法也简单,就是做一个计数器(计数器的时候通常是一个RTT时间,也就是数据包一个来回的时间)超过这个时间我们就进行重新发送。这里要注意的就是,计时器的设置和中断了。考虑丢包的情况如下图所示(只要考虑发送端会添加这些东西):
这里写图片描述

但是,大家可以观察我们要进行的这个可靠传输的过程,是不是我们的大部分时间都在等待一个个ACK应答包,这造成了时间的巨大浪费。但是,如何改进这个问题呢?有没想起我们在学习计算机基础的CPU执行命令的流水线。思路是完全一样的,我们像流水线一样,一次发送多个包,然后依次发送ACK包。这就要求我们要设计一个滑动窗口,也就是缓冲,存储这些数据包,直到受到ACK才将滑动窗口进行前移。那么,如果在流水线中出现的重传的问题。解决办法有两种:回退N步或者选择重传。顾名思义,回退N步就是在出现丢包的情况,将滑动窗口拉回到N步前,全部重发。(简单粗暴,但是效率慢)。选择重传:出现丢包的情况,只重传指定的包,进行滑动窗口的移动。这就是我们的TCP的滑动窗口机制啦,大家看图就好。
这里有一个动画可以非常形象的进行展示,大家可以到我的github上下载下来.(稍后上链接)

五. TCP是如何进行拥塞避免的?
我们还是先从原因开始:
拥塞是如何产生的? 数据包太多了,路由器的缓冲(可以存储的数据包)有限,超过这个限度就会产生拥塞,即然超过这个限度,就会产生丢包。
所以,超时重传和冗余ACK包(相同数据传了多份)是我们判断是否产生拥塞的主要依据。

所以,进行拥塞避免的办法就如同我下面总结的:
1.乘性减:一旦出现了拥塞的情况(重传和冗余ACK包),拥塞窗口(控制流量)减半(控制流量减半)。
2.加性增:在没有出现拥塞的情况下,拥塞窗口随时间线性增长,每次增长一个单位。
所以,加性增、乘性减的拥塞控制经常呈现锯齿形,如下图所示:
这里写图片描述
3.慢启动:在刚开始进行连接的时候,拥塞窗口非常小,但是呈现线性增长(每次都进行翻倍)。直到出现第一次拥塞或者超过阈值,进行上面的乘性减和加性增的操作,具体的图像如下图所示:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/github_33873969/article/details/79422188