目录
1.UDP协议:
- UDP协议的特点:无连接、不可靠传输、面向数据报和全双工。
- UDP报文最大长度是2个字节,2个字节表示的范围就是0~65535,也就是64kb。所以如果需要使用UDP传输一个比较大的数据,就需要考虑进行拆包,把一个大的数据报拆成多个小的。
- 校验和的作用是检查数据是否出错了,因为传输过程中受到一些干扰是很容易导致传输的数据出错。举个例子:去超市买菜,买完后核对下是不是这么些菜,这个就相当于校验和。
- UDP的校验和使用一个比较常见的CRC算法(循环冗余校验),把UDP报文中每个字节都进行累加,加和放到一个俩个字节的数字中,加的过程如果溢出了那就溢出吧,最终得到的结果就是校验和。
- 发送方发送的时候就先计算一个校验和;接收方按照同样的规则再算一遍校验和,来和发送方的校验和比对,如果相同说明数据没问题,如果不同说明数据出错了。
- 应用层自定义类型,1.确定传输哪些信息(需求)2.确定数据的格式(http、xml、json、protobuffer)。
2.TCP协议:
- TCP的基本特性:有连接、可靠传输、面向字节流、全双工。可靠传输是TCP中最核心的特性。
- 确认应答机制(1),是TCP保证可靠性的最核心机制。A给B发送信息后,B回复“收到”,这个收到就是应答报文,也成为ack报文。普通报文,ACK这一位为0;应答报文,ACK这一位为1。
- 为了避免发送的信息出现“后发先至”的情况,这种情况是网络基本结构导致的,在确认应答这个机制中,引入序号来保证不出现歧义。32位序列号针对请求数据进行的编号;32位确认序号只是针对ACK报文有效。TCP是一个字节流的协议,编号的时候也是以字节为单位进行编号的。
- 每个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发。
- 确认应答描述的是,数据报顺利到达对方,对方也给了个响应。但是传输的过程中有可能会丢包,如果丢包此时就需要考虑超时重传!
- 超时重传机制(2),(针对确认应答做出的补充,确认应答指的是一切正常的情况下,如果传输中间丢包了就涉及到了超时重传)。站在发送方的角度来看没有收到ACK,发送方不知道是发的数据丢了还是ack丢了。如果是发送方的信息丢了超时重传没有问题;可如果是ACK丢了,接收方就会重复收到信息,TCP就会针对相同的信息进行去重(保证了应用层代码通过socket读取数据的时候,读到的不是重复的数据)。
- 超时重传的时间如何确定。系统里面都会有配置项来描述超时的时间阙值,如果第一次发生丢包,发送方就会在到达时间阙值之后进行重传。如果重传的数据仍然无响应,还是继续超时重传,第二次的超时时间比第一次更长。超时重传的时间不是均等的,而是逐渐变大的。
- 这样的重传,重试几次之后,仍然无法传输,就会尝试重置TCP连接(断开重连)。如果还是连不上,则直接释放连接。
- ACK(应答)只是告诉发送方收到数据了;响应是携带业务上的数据。ACK是系统内核负责的会在收到请求后立刻返回;业务上的响应这个取决于你的代码。
- 连接管理机制(3),描述的是TCP建立连接和断开连接的过程。TCP的连接只是一个逻辑上的“虚拟连接”。
- 什么是建立连接,主机A和主机B建立了连接:主机A的系统内核中记录了一个数据结构包含了和他连接的对象B的(IP、端口和使用的协议等)。主机B的系统内核中记录了一个数据结构包含了和他连接的对象A的(IP、端口和使用的协议等)。
- 建立连接是双方建立一个相互认同的关系,“三次握手”。通信的双方各自向对方申请,尝试和对方建立连接,然后在各自给对方回应,建立连接的过程其实是四次的数据交互,但是中间俩次可以合并到一起,因为ack和syn是操作系统内核触发的,是立即发送的;因为时机完全相同操作系统就会把俩个包合并成一个。也可以是四次握手,但是没有必要!
- SYN(同步报文段)这一位如果为1,说明这是一个同步报文段(尝试和对方建立连接的)
- 为什么要建立连接!?a:检查一下当前的网络是否是畅通的,三次握手建立连接并不传输任何业务数据。b:三次握手也是在检查通信双方的发送能力和接受能力都是正常的。c:三次握手过程中也在协商一些重要的参数
- 俩个重点的tcp状态:LISTEN,服务器启动后绑定端口号之后(new ServerSocket完成)表示手机开机,信号良好(就可以让别人给他打电话!)。ESTABLISHED:连接建立好后的稳定状态(表示电话接通,可以说话了)。
- 断开连接,双发取消相互认同的关系,通信双方各自向对方申请断开连接,再给对方回应,“四次挥手”。
- 四次挥手中俩个重要的tcp状态。CLOSE_WAIT,等待代码中调用close操作。TIME_WAIT,主动发起关闭的一方会进入TIME_WAIT,处理完最后一个ack之后不会立即释放而是保持一定时间(万一最后的ACK丢了,还有机会进行重传!);如果最后一个ack丢包了,此时B就会重新发一次FIN,如果等了一会发现FIN还没有重传过来说明ack顺利到达了,TIME_WAIT只需要等待2MSL(网络上的俩个位置之间传输数据消耗的最大时间)即可。
- 三次握手必须是接收端先握,四次挥手谁先挥手都可以,接收方发送的ACK和FIN不在同一时刻所以画图的时候需要分开,也不是100%不在一起。ACK是内核触发的,FIN是调用close方法。
- 滑动窗口(4),上述的确认应答、超时重传和连接管理都是为了提高可靠性;这里的滑动窗口为的是提高tcp的传输效率。tcp的效率再怎么提高也比不上udp的传输效率。
- 关于滑动窗口的含义来举个例子:我想到了个好玩的事情要和女神分享,我发送一条信息,她也回我一条信息,这样一来一回时间浪费的很多。引入了滑动窗口之后变成了这样,我直接连5条信息,女神回我一条我再发一条,回我一条再发一条,在这个过程中我等待女神回复的信息数量都是5。把这直接连发5条的信息的量称为窗口大小,窗口的大小是字节为单位。把不需要等待,直接发送的数据量称为窗口的大小。
- 在滑动窗口的机制下,出现丢包(响应的ack丢了和传的数据丢了)。a.响应ack丢了,这种情况不要紧,因为可以通过后续的ack来确认(大学毕业证都有了,那初中高中毕业证肯定也有了!)。b.传的数据包丢了,ack就会提醒发送方缺少哪里的数据,需要重传!这里重传的是缺少的包,没缺的不用重传,这种效率比较高的重传称为“快速重传”(搭配滑动窗口机制的超时重传)。如果传输的数据很多批量传输,遵守快速重传;如果传输的数据很少,仍然按照超时重传来进行,只要丢包重传都是超时重传,快速重传是超时重传的特殊情况!
- 滑动窗口效率高不高取决于窗口的大小,窗口越大效率越高;但是窗口为无穷大时虽然效率最大,但是不可靠了。发送的速度是快了但是接收方吃不消,如果发的很快,接收方处理速度跟不上就会导致接收方丢弃一部分数据,tcp为了保证可靠性还要重传这些数据,让不富裕的家庭雪上加霜.....这时候就需要有其他机制来对发送方的发送速度作出限制(流量控制)。
- 流量控制(5),在滑动窗口的基础之上对速度做出限制,就是限制发送方的窗口大小不要太大了,根据接收端的处理能力来衡量发送方的速度。因为接收端处理数据的速度有限,如果发送端发的太快就会导致接收端的缓冲区满了,这个时候发送端继续发送数据就会造成丢包,继而引发一系列丢包重传的连锁反应,这就是为什么要引入流量控制的原因。
- 窗口大小多少合适呢,这个得问问接收方觉得多少合适;接收方根据自己的接收能力来反向影响发送方接下来的发送速率。接收方的接受速率如何进行量化?接收方使用接收缓冲区的剩余空间大小,来作为发送方发送速率(窗口大小)的参考数值。
- 接收方B收到A的数据之后,就会在ACK应答报文中,把当前接收缓冲区剩余空间大小的值反馈给发送方。每次ack都会调整窗口的大小。
- 如果接收方缓冲区满了就会把窗口置为0,这时发送方不再发送数据,但是需要定期发送一个窗口探测数据报,使接收端把窗口的大小告诉发送方。
- 拥塞控制(6),虽然滑动窗口机制可以提高tcp的效率但是如果在刚开始阶段就发送大量的数据就会引发很多问题。从少量开始,逐渐变大,如果丢包再变小,反复动态调整。
- 流量控制和拥塞控制都是在控制发送方的窗口大小,当这俩有分歧的时候,谁小听谁的!
- tcp实现拥塞控制具体方式,tcp引入了慢启动机制,先发少量的数据摸清当前网络的拥堵程度如果不丢包就要放大拥塞窗口(拥塞控制下的那个窗口大小)。当拥塞窗口的大小超过这个阈值的时候,不再按指数方式增长而是线性方式增长。每次超时重传的时候,慢启动的阈值会变成原来的一半,同时拥塞窗口置为1。
- 来给上述的实现方式举个例子:和对象刚谈恋爱的时候处于热恋期感情指数增长,过了热恋期慢慢的就趋于稳定的线性增长;突然有一天吵架了闹分手感情一落千丈,后来和好了又会进入热恋期不过这时的热恋时间就小于第一次.....
- 拥塞控制归根结底就是为了tcp协议尽可能快的把数据传输给对方,但是又避免给网络造成太大压力的折中方案。
- 延迟应答(7),提高传输效率的机制又是基于流量控制来引入提高效率的机制。
- 延迟应答的作用就是慢一点应答尽可能的让窗口大一点。
- 捎带应答(8),基于延时应答的基础上引入的。
- TCP中只要把数据传过去了,对方收到之后就会立即由内核返回一个ack确认报文;响应的数据则是由应用程序来负责传输的。
- 本来ack是立即就要返回的,但是由于延时应答稍微等了一会,正巧业务上也要返回这个响应,此刻就把俩个报文合二为一了。捎带应答是偶然发生的,因此四次挥手也有可能变成三次,但是不是100%的。
- 来给捎带应答举个例子:我在沙发上坐着看电视,突然渴了但是太懒不想动,于是就稍微等一会,过了一会想上厕所了,就起来一趟同时完成喝水和上厕所。这俩操作不是100%合并到一起的。
- 面向字节流(9),这里有一个典型的问题叫做“粘包问题”。
- TCP(或者其他面向字节流的传输方式)都有一个接收缓冲区。A的应用程序就需要从接收缓冲区中读取数据,由于是面向字节流的所以A无法确定从哪里到哪里是一个完整的应用层数据报。要想解决粘包问题就要在应用层协议这里进行区分,只要定义应用层数据报协议的时候明确包和包之间的边界就可以了。
- 典型的方法有俩种:通过分隔符或指定包的长度(在数据包的开头位置声明长度)。
- TCP自身对于应用层数据报是无法做区分的;UDP面向数据报是不存在这个问题的,一个UDP数据报就是对应一个应用层报文。
- TCP的异常处理(10),连接异常了。
- a)程序崩溃了;进程异常退出了,操作系统会回收进程的资源,包括释放文件描述符表。这样的释放操作就相当于调用了对应的socket的close,执行close就会触发FIN报文,接下来就是四次挥手了。(这种情况和普通的四次挥手没啥区别)
- b)正常关机;关机的时候会先强制结束所有的用户进程,和上述的那个进程崩溃类似,系统内核会进行文件描述符表的释放操作,进一步四次挥手。
- c)主机掉电(突然的状况);掉电的是接收方,发送方不知道对面挂了,继续发送数据此时发的数据,没有ack了就会触发超时重传,重传几次之后仍然无应答就尝试重置连接,最终放弃连接。掉电的是发送方,此时接收方只能等着(也不是干等着,过了一会还会发送心跳包,来确认对方是否还在,如果对方不返回心跳包说明心跳遗失了,那就放弃连接)。
- d)网线断开;和主机掉电的情况一样,只不过通信双方的主机都还正常,还是按照上述俩种情况分别来进行。
- 如何使用UDP来实现可靠传输,考察的是TCP!
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹