TCP/UDP协议

目录

一、应用层

二、传输层

​编辑

2.1 UDP协议

2.2 TCP协议

2.2.1 TCP原理

2.2.1.1 确认应答机制

2.2.1.2 超时重传机制

2.2.1.3 连接管理机制(三次握手,四次挥手)

2.2.1.4 滑动窗口机制

2.2.1.5 流量控制机制

 2.2.1.6 拥塞控制机制

2.2.1.7 延时应答机制

2.2.1.8 捎带应答机制

2.2.1.9 面向字节流(粘包问题)

2.2.1.10 TCP异常


一、应用层

1、什么是应用层协议?

程序员根据用户需求来制定的应用内部协议

2、设计一个应用层协议需要的步骤:

1、明确传输的信息

2、明确组织数据的格式

二、传输层

应用层是直接和程序猿打交道的,而传输层实际上是不直接和程序员打交道的,但是由于网络编程会用到socket,一旦我们利用socket进入代码内部调解bug的时候就进入了传输层。

传输层的协议有很多,最常见的的两个:UDP和TCP

TCP和UDP之间的区别和联系:

1、TCP有连接,UDP无连接

2、TCP有可靠传输,UDP无可靠传输

3、TCP面向字节流,UDP面向数据报

4、两者都是全双工

此处讲下TCP的特点

TCP有连接体现在服务器需要和客户端进行连接才能通信,下图

TCP面向字节流体现在都是输入和输出都是进行的流操作,下图

TCP全双工则是因为它能同时输入流操作和输出流操作,下图

2.1 UDP协议

首先先介绍下UDP的报文格式

报文长度:

UDP的报文长度是两个字节,范围是0-65535(0-64k),这也揭示了UDP数据报的一个知名的缺陷,当面临传入的数据大于这个范围的时候,只能进行分包处理(就是把一个完整的数据拆成多个数据报),再将接收的数据进行整合。

但是这样子操作的话,整合的过程可能会出现丢包或者拼接包顺序一致的情况就相当麻烦,所以对于数据量较大的而言,通常用TCP来完成。

校验和:

在现实网络传输的过程中,我们知道传递的本质是光信号和电信号,但某些情况下数据在传输的过程中会受到电磁场的干扰,会导致传输的数据出现错误,因此需要我们通过校验和进行验证。

校验和验证就一定准确嘛?

答案是否定的

校验和验证不一定准确,只是在某种特定范围保证准确性,只能保证如果校验和不对,此时你的数据一定不对,如果校验和对,但是数据也有一定概率是错误的

举一个例子:

假如今天我去买菜,我需要买鸡蛋、西红柿、青菜、肉四类菜,但是我是买了四样菜,只是种类不同,像这种校验和检测就不一定正确,但是我假如买了5类菜,校验和一定能检测出错误。

2.2 TCP协议

首先先介绍下TCP协议段格式

1、/目的端口号:表示数据是从哪个进程来,到哪个进程去;

2、32位序号/32位确认号:后面详细讲;

3、4位TCP报头长度:表示该TCP头部有多少个32bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60;

4、6位标志位:

        URG:紧急指针是否有效

        ACK:确认号是否有效

        PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

        RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

        SYN:请求建立连接;我们把携带SYN标识的称为同步报文段

        FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段

5、16位窗口大小:后面再说

6、16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光包含TCP首部,也包含TCP数据部分

7、16位紧急指针:标识哪部分数据是紧急数据;

8、40字节头部选项:暂时忽略;

2.2.1 TCP原理

TCP对数据传输提供的管控机制,主要体现在两个方面:安全和效率

这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率

2.2.1.1 确认应答机制

1、什么是确认应答机制:

是可靠传输中的核心机制,即为发送数据给对方后,能够确认对方是否收到。其关键就是接收方在收到消息后,会给发送方一个应答报文(ack),表示自己已经收到了。

举例说明:

某天我给女朋友发送消息:

如果我发了多次消息,由于网络上,数据的接受可能会出现一个后发先至的现象,可能就会出现一些问题。

TCP是如何解决上述的问题的呢?

1、对于上述例子的解决:

我们可以通过对消息进行编号,进而解决这个问题

这个时候就能确定发送方和接收方收到的消息是一致的了

2、TCP内部是如何实现编号的呢?

但是在某些时刻,流量达到了峰值,可能会引起部分数据丢包,如果包丢了,接收方就收不到了,自然不会返回ack。

发送方迟迟拿不到应答报文,在等待一段时间后,还没有收到应答报文,发送方就视为刚才的数据丢包了,此时就会重新发送一遍,也就是接下来所说的超时重传机制

2.2.1.2 超时重传机制

1、什么是超时重传机制

通俗一点来说,发送方给接收方发送消息时,但是却因为消息在传输过程中丢了包,而操作系统内部感知到了,触发了重传机制,就能保证对方能够收到这条消息。

发送方对于丢包的判断,是一定时间内,没有收到ack,但是有两种情况发送方是区分不了这两种情况的~~

1、数据直接丢了,接收方没有收到,自然不会发ack

2、接收方收到数据了,返回的ack丢了

对于情况1来说是正常的,但是对于情况2来说就是不可行的,举例一下,如果你收到了两次转账记录,但是收到的前只有第一次转账的呢?

2、去重操作

对于情况2来说,主机B收到重复数据,那么TCP协议需要能够识别出哪些包是重复的包,会在接收缓冲区根据收到的数据的序号,把重复的丢弃掉,保证应用程序读到的数据只有一份。

重传一定能实现嘛?

重传的数据可能会连续丢包,多半情况下是网络出现了严重问题,TCP针对多个包丢失的处理思路是继续超时重传,但是每丢包一次,就会增加超时等待时间,经过连续多次重传都无法得到ack,TCP就会尝试重置连接,如果重置连接也生效,TCP就会关闭连接,也就是放弃网络通信,能重传就重传,实在传输不了,就会关闭连接,尽最大可能完成传输~

一切顺利,使用确认应答保证可靠性;出现丢包,使用超时重传作为补充,这两个机制,是TCP可靠性的基石。

2.2.1.3 连接管理机制(三次握手,四次挥手)

1、如何建立连接

客户端和服务器之间,通过三次交互,完成了建立连接的过程,客户端时主动发送连接请求的一方,客户端会先发送一个SYN同步报文给服务器。

举一个例子:

假如服务器是我,客户端是我朋友,我们在一起打游戏,首先我们会进行语音连麦,我会说“喂,可以听到嘛”,这个时候他会给我说能听到(相当于ACK),这时我能知道我的麦克风和耳机都没问题,随后我朋友会说到“喂,你也能听到我的声音嘛”,我也会回复我能听到,这时候他就知道他的设备没问题。

这个时候可能会有人发送疑问,这不是四次握手嘛,哪里来的三次握手?

那是因为中间的ACK和SYN都是由内核态同一时刻触发的,所以会把两者封装在一起,形成了一个整体,每次传输数据的时候,都要经过一系列的封装和分用才能完成传输,封装和分用两次肯定不如封装一次高效。

为啥不是两次?

不可以。意味着缺少最后一次,此时客户端这边关于发送接收能力正常的,情报是完整的,但是服务器这边是残缺的。服务器不知道自己的发送能力是否ok,也不知道客户端的接收能力是否ok ,此时此刻,服务器对于当下能否满足可靠传输,心里是没底的,这第三次交互,就是为了给服务器吃一个定心丸。

为啥不是四次?

可以。但没必要,反而浪费了资源,可以一次进行封装。

2、如何断开连接

通信双方,各自给对方发送一个FIN(结束报文),再各自给对方返回ACK。

有人可能会好奇,为什么这里不是四次挥手?

三次握手,ack和syn是同一时机触发的,因为ack是内核完成的,会在收到fin的时候第一时间返回;fin则是应用程序代码控制的,在调用socket的close方法的时候才会出发fin

2.2.1.4 滑动窗口机制

1、滑动窗口的意义:

在保证可靠性的同时,提高传输效率

2、如何提高传输效率

在前面的应答机制可以知道,要执行新的操作,那么必须要先收到ACK应答。

3、滑动窗口的本质

批量发送数据,一次发送多条数据等待一波ACK

1)窗口的大小指的是无需等待确认应答而可以继续发送数据的最大值。上图中的窗口大小就是4000个字节(四个段)

2)发送前四个段的时候,不需要等待任何ACK,直接发送

3)收到第一个ACK之后,滑动窗口向后移动,继续发送第五个段的数据;依此类推

4)操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉

5)窗口越大,则网络的吞吐率就越高

此图就是收到第一个ACK之后,滑动窗口向后移动,继续发送第五个段的数据;依此类推

但是是不是可能会出现丢包的情况呢?

答案是肯定的

注意:

滑动窗口的窗口大小, 到底要多少合适??窗口越大, 传输效率就越高,但是内存消耗就更大.窗口越小,传输的效率就越低,内存的消耗也就小了.不仅仅是内存,还有一些东西会影响到"窗口大小"典型的,接收方的处理速率~如果接收方处理的速度快(应用程序从队列中取的速度快)如果接收方处理的速度慢(应用程序从队列中取的速度慢)此时就需要限制一下发送方的窗口大小.根据接收方的处理能力,来限制~限制的方法就是:流量控制!!

2.2.1.5 流量控制机制

1、什么是流量控制机制?

流量控制,是滑动窗口的延伸,目的也是保证可靠性。

2、为什么要引入流量控制机制?

因为在滑动窗口中,我们不能为了只追求传输速率而不考虑接收方的感受。当发送方的速度很快,而接收方接收不过来的时候,就会出现丢包的情况。这个时候发送仍然得重传。因为我们引入流量控制机制,就是为了能够衡量接收方得处理速度,此时使用接收缓冲区的剩余空间大小来衡量当前的处理能力。

 2.2.1.6 拥塞控制机制
虽然 TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。 因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。 TCP 引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

拥塞控制衡量的内容

从发送方到接收方整个链路之间的拥塞情况。因为A能够发送多快,不仅仅是基于B的接收速度,与整个链路的处理能力是密不可分的。而我们很难对其中一些设备进行衡量,所以拥塞控制的处理方式,就是通过“实验”来找到一个比较合适的范围。

2.2.1.7 延时应答机制

什么是延时应答机制?

流量控制的延伸,流量控制是让发送方发送的不要太快,而延时应答就是在这个基础上,尽量扩大滑动窗口的大小。如果接收数据的主机立刻返回应答报文ACK,这时候返回的窗口可能比较小。

2.2.1.8 捎带应答机制

1、什么是捎带应答机制?

它是延时应答的延伸。

在延迟应答的基础上,客户端服务器在应用层也是 “一发一收” 的。比如我给朋友发消息:你在干嘛?朋友回复:玩游戏;那么这个时候ACK就可以搭顺风车,和服务器回应的 "玩游戏" 一起回给客户端。
因为延时应答的存在,导致ACK不一定是立即返回的,如果当前的延时应答,导致ACK的返回时机(是内核响应的)和应用代码中返回的响应(应用程序返回的)时机重合了,就可以把这个ACK和响应数据,合二为一。

2.2.1.9 面向字节流(粘包问题)

1、粘包问题

不仅仅TCP有粘包问题,其它面相字节流也存在这样的机制

这里的TCP粘包问题指的是应用层数据报,在TCP的接收缓冲区中若个应用数据报就会粘在一起,导致分不清发送过来的数据。

2、解决办法

在应用层添加包的边界,比如用“;和\n”来对不同的包进行分割,就没有啥问题了。

使用Java中自带的BufferedReader和BufferedWriter,也就是带缓冲区的输入字符流和输出字符流,通过写入的时候加上\n来结尾,读取的时候使用readLine按行来读取数据,这样就知道流的边界了,从而解决了粘包和半包的问题。 

2.2.1.10 TCP异常

①进程的终止:

这个是在进程毫无防备的情况下,突然关闭进程,就类似于在任务管理器中直接关闭进程。

而TCP的连接是通过socket这个api来建立连接的socket本质上是打开一个文件,文件其实就存在于进程的PCB中的文件描述符表,每打开一个文件,文件描述符表就会增加一项,每关闭一个文件,文件描述符表就会删除一项,而此时直接杀死进程,PCB就没了,相应的里面的文件描述符表也就没了,就相当于文件自动关闭了,而这其实和手动调用socket.close()一样,也会触发四次挥手。因此这样就和正常关闭是一样的。

②机器关机:

这里的机器关机指的是通过正常流程来关闭机器,这样就会让操作系统杀死所有进程,从而关闭机器,这也就和上面的手动调用close方法是一样的,也是正常的

③机器掉电/网线断开:

这就类似于台式电脑直接拔掉电源,此时操作系统是不会有任何反应时间的,更不会有任何的处理措施,下面是两种常见的情况:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值