网络原理详解(应用层+传输层(UDP/TCP)+网络层(IP)等各层协议及功能详解)


前言


一、应用层(后端开发必知必会)

1.自定义协议

这一层,也有很多现成的协议.(后面还会重点介绍HTTP协议)
也有很多时候,是需要程序猿自己定义协议.

定义协议:
做出如下设计:
1.明确当前请求和响应中包含哪些信息(根据需求来的)
2.明确具体的请求和响应的格式.

网络上,传输的数据,本质就是字符串。Java 写代码,都是各种对象。
[序列化]:最后在发送数据的时候,就需要把对象转成(二进制)字符串
[反序列化]:在收到数据的时候,也需要把(二进制)字符串转换回对象
在这里插入图片描述
实际上,上述这样的格式约定,咋搞都行.任意进行约定的.只要保证,客户端和服务器遵守同一个约定即可!!

实际开发中如何约定:
1.实际开发中,客户端和服务器,往往是两伙不同的人分别开发的。为保证,双方的配合是有效的。在开发之前,就要共同商量一下这里的数据格式如何确定(具体怎么设定无所谓,一定要统一)
2.指定一个人,由这个人整理出一个最终的前后端交互的数据格式规范。发一个邮件出来,抄送客户端和后端这里的相关开发,还会抄送给测试。双方再按照这个规则进行各自写代码.测试也需要根据这个规范设计测试用例.
3.等到双方都把代码写完之后,客户端和后端先各自测各自的…双方都测试完了,还需要进行联调。把两份代码的程序放到一起一个环境中,试试看能不能正确通信。
4.客户端和服务器这边的开发,以及测试,都坐到一起。配合完成这个工作。

2.通用的协议格式

虽然说,自定义的协议格式,是可以任意的.但是为了避免出现过于天马行空的设计。
“通用的协议格式”,参考这些格式,就可以对咱们的协议设计产生重要的指导作用

1.xml(越来越少)

是以成对的标签,来表示"键值对”信息,同时标签支持嵌套,就可以构成一些更复杂的树形结构数据.
在这里插入图片描述
在这里插入图片描述

优点: xml非常清晰的把结构化数据表示出来了
缺点:表示数据需要引入大量的标签,看起来繁琐,同时也会占用不少的网络带宽.
(国内,最贵的硬件资源,就是网络带宽!!)

xml里的标签都是程序猿自定义的.
html里的标签,都是有一套标准规定好的。
(html可以视为是xml的特化版本)

2. json(最流行一种数据组织格式)

本质上也是键值对,看起来,比xml要干净不少

在这里插入图片描述
优势:相比于xml,表示的数据简洁很多.
可读性非常好的.方便程序猿观察中间结果,方便调试问题.
劣势:终究是需要花费一定的带宽来传输key的名字的.

json对于换行并不敏感,如果这些内容全都放在同一行,也是完全合法的.
一般网络传输的时候,会对json进行压缩(去掉不必要的换行和空格),同时把所有数据都放到一行去,整体占用的带宽就更降低了.(影响到可读性)
也有很多现成的json格式化工具.

二、传输层(UDP,TCP)

1.UDP的结构

UDP基本特点:无连接,不可靠传输,面向数据报全双工
在这里插入图片描述
在这里插入图片描述

1.端口

一次通信,涉及到5元组:源端口,目的端口,源ip,目的ip,协议类型

以下数字,要求大家能够熟练背诵!!最常用的一些数据!!
在这里插入图片描述
端口号用使用范围:1025~65535
1-1024这个范围的端口号(知名端口号(known port)),系统赋予了特定的含义,一般也不建议咱们使用。
你当然也可以写个程序,使用1024之前的端口。(需要你的程序有管理员权限)

2.UDP报文长度

UDP报文长度:2字节(64kb)。不够用
此时,能否把这个长度给改大?分配4个字节表示这个UDP长度~是否可行呢??
相当困难,甚至完全不可行。(因为标准已经统一,很难改变)
可以采用以下两种来解决,第二中最佳。
在这里插入图片描述

3.UDP的校验和具体实现

UDP的校验和具体是咋实现的?使用了一种简单粗暴的CRC校验算法.(循环冗余校验和)
1)把UDP数据报中的每个字节,都依次进行累加。
2)传输数据的时候,就会把原始数据和校验和一起传递过去.
3)接收方收到数据,同时也收到了发送端送过来的校验和(旧的校验和)。接收方按照同样的方式再算一遍,得到新的校验和。
4)如果旧的校验和和新的校验和,相同,就可以视为数据传输过程中,是正确的。如果不同,则视为传输过程中数据出错了。

2.TCP重点&考点

TCP特点:
有连择,可靠传输,面向字节流全双工
(内核实现的可靠传输,写代码的时候,是感知不到的)(可靠传输实现机制)

1.tcp结构

在这里插入图片描述
32位序号(数据编号)
只要知道这一串字节的开始编号,以及数据的长度,每个字节的编号自然也就知道了。
只需要在tcp报头中,把这一串字节第一个字节的编号,表示出来,再结合报文长度,此时每个字节的编号就确定。

32位确认序号
这个字段就是给应答报文使用的.
TCP核心特性,结合这些特性,进一步的理解这里的报头结构。

数据:
tcp 的载荷数据,包含若干字节.

想知道完整的TCP具体都有哪些设定??在RFC标准文档中找(最权威的资料)

2.确认应答(可靠性的核心机制)

1.发送方,给接收方发过去的数据,接收方会返回一个ack应答报文。
2.确认序号:表示该序号之前的数据已经收到/索要该序号之后的数据。
在这里插入图片描述
出现丢包?
网络负载越高,越繁忙,就越容易丢包.

3.超时重传(确认应答的重要补充)

如果我收不到应答,就要尝试重传
等待一定时间,超过一定的时间之后,再进行重传.
超时重传,相当于针对确认应答,进行的重要补充.(是TCP可靠性机制的有效补充)

超时重传会导致导致数据重复吗?
在这里插入图片描述
去重:
在这里插入图片描述
为啥重传的时候,数据就能传过去??
在这里插入图片描述
超时时间不是一个固定的值,会随着超时轮次的增加,而进一步增加。
在这里插入图片描述

4.连接管理(三握四挥)

1.建立连接(三次握手)
2.断开连接(四次挥手)

三次握手

三次握手:使用打招呼来触发"特定场景",发一个打招呼的数据(这个数据并不会携带业务信息)
握手: handshake
tcp要想保证可靠传输,可靠传输的前提,是网络路径得畅通。
tcp三次握手,就是要验证网络通信是否畅通,以及验证每个主机的发送能力和接收能力是否正常。

三次握手的功能主要就是两方面:
1.投石问路,验证通信路径是否畅通,双方的发送/接收能力是否正常.
⒉协商必要的参数,使客户端和服务器使用相同的参数进行消息传输.

在这里插入图片描述
在这里插入图片描述
ACK是应答报文.
SYN申请建立连接的请求.(“同步报文段”)
在这里插入图片描述
三次握手,第一次syn一定是客户端发起的.(客户端是主动的一方)
三次握手和代码的对应关系:
在这里插入图片描述
三次握手,为啥是三次?
1.恰好三次,就能验证好双方的发送和接收能力均正常,并且把这样的信息同步给了双方.
2.是两次是否可以?
很明显,不可以的~虽然两次握手,是可以验证完成通信能力的正确性,但是服务器这边还不知道这样验证通过的信息.
3.四次是否可以??
可以,但是没必要.(把中间这次,拆成两次)一次就行了,能合并就合并,拆成两次,降低效率.

四次挥手

断开连接,四次挥手
三次握手,必然是客户端主动发起.
四次挥手,不一定.服务器也可以主动发起.大多还是客户端主动的.
在这里插入图片描述
在这里插入图片描述
如果服务器,始终不进行close,会咋样?客户端的连接就始终不关闭嘛?
在这里插入图片描述
如果通信过程中,出现丢包了,又咋处理?
这里也是涉及到超时重传的.
三次握手,和四次挥手,也都是带有重传机制的.
尽可能重传,如果重传仍然失败,连续多次,此时仍然会单方面释放连接.
在这里插入图片描述
同理,A这边等待多久才能释放连接?
在这里插入图片描述

在这里插入图片描述

5.滑动窗口(提高传输效率)

提高传输效率.(更准确的说,是让TCP在可靠传输的前提下,效率不要太拉胯)﹑(亡羊补牢)
滑动窗口,是一个“形象的比喻”,实际上本质就是批量发送数据.
这样就可以缩短等待时间,比之前能提升一定的效率(缩短不是没有,仍然需要花时间等待,传输效率仍然不会比UDP更高)

在这里插入图片描述
ACK丢了
在这里插入图片描述
数据报丢了
在这里插入图片描述
在这里插入图片描述

6.流量控制(站在接收方的角度制约发送速率)

(作为滑动窗口补充)
滑动窗口,窗口越大,传输效率越高.
但是窗口也不能无限大.如果窗口太大了,就可能使接收方处理不过来了.或者是使传输的中间链路出现处理不过来。
这样就会出现丢…就得重传了…窗口大并没有提高效率,反而还影响了效率.
流量控制,就是给滑动窗口踩踩刹车.避免让窗口太大,导致接收方处理不过来

流量控制,就是根据接收方的处理能力,来限制发送方的发送速度(窗口大小)
如何衡量接收方的处理速度??
此处就使用接收缓冲区剩余空间大小来作为衡量指标.(如果剩余空间越大,应用程序消费数据的速度就越快.)
此处,就会直接把接收缓冲区的剩余空间大小,通过ack报文反馈给发送方,作为发送方下一次发送数据,窗口大小参考依据。
在这里插入图片描述
在这里插入图片描述

7.拥塞控制.(站在中间链路角度制约发送速率)

总的传输效率,是一个木桶效应,取决于最短板.
拥塞窗口:在拥塞控制机制之下,采用的窗口大小.
在这里插入图片描述
TCP中,拥塞控制具体是这样展开的:
1.慢启动:刚开始进行通信的时候,会使用一个非常小的窗口,先试试水.
如果网络拥堵,一上来又搞了一个很大的流量过来就让本来不富裕的网络带宽,雪上加霜了。
2.指数增长:在传输通畅的过程中,拥塞窗口就会指数增长(* 2)
指数增长速度是极快的.不能不加限制否则就会出现非常大的值。
3.线性增长:指数增长当拥塞窗口达到一个阈值之后,就会从指数增长,转换成线性增长(+n)
线性增长,也是增长,就会使发送速度,越来越快.
快到一定程度,接近网络传输的极限,就可能会出现丢包了。
4.拥塞窗口回归小窗口:当窗口大小增长过程中,如果传输出现丢包,认为当前网络出现拥堵了。
此时就会把窗口大小调整成最初的小窗口,继续回到之前指数增长+线性增长的过程。另外此处也会根据当前出现丢包的窗口大小,调整阈值(指数增长->线性增长)
在这里插入图片描述
在这里插入图片描述

8.延迟应答(在合理的范围内尽量提高窗口大小)

提高传输效率的机制.围绕滑动窗口琢磨的。
是否有办法,在条件允许的基础上,尽可能的提高窗口大小呢??
需要在返回ack 的时候,拖延一点时间.利用拖延的这个时间,就可以给应用程序腾出来更多的消费数据的时间.接收缓冲区的剩余空间,就会更大了!!!

8.捎带应答,在延时应答的基础上,引入一个进一步提高效率的方式.
延时应答,是让ack 传输的时机更慢.
捎带应答,基于延时应答,让数据进行合并.
在这里插入图片描述
数据报从两个合并成一个,效率会有明显的提升的。主要还是因为这里每次传输数据都是需要封装分用的。
能合并的原因,一方面是时机上是可以同时的。一方面是ack数据本身不需要携带载荷和正常的数据也不冲突。
完全就可以让这一个数据报,既能携带载荷数据,又能带有ack的信息.(ack标志位,窗口大小,确认序号)

9.面向字节流(粘包问题.应用层数据报在tcp 缓冲区中区分不开了)

在面向字节流这样的情况下,会产生一些其他的问题.
粘包问题.
发送方一次性是可以发送多个应用层数据报的.但是接收的时候,如何区分,从哪里到哪里是一个完整的应用数据报??
如果没设计好,接收方就很难区分,甚至会产生bug !!
在这里插入图片描述
在应用层,来解决这个问题.
1.应用层协议中,引入分隔符.区分包之间的边界
2.应用层协议中,引入"包长度",也能区分包之闻的边界.

1)使用\n约定包之间的分隔符.
在这里插入图片描述

2)使用包的长度来进行区分
在这里插入图片描述

粘包问题,不仅仅是tcp 才有的.
只要是面向字节流的机制(文件)也有同样的问题。解决方案也都是一样,要么使用分隔符,要么使用长度。
尤其是在自定义应用层协议的时候,就可以使用这样的思想来解决问题了。
相比之下,前面介绍的这几种方案:
xml/json都是通过分隔符来区分包的。protobuffer 则是通过长度来区分的.

10.TCP异常情况的处理(进程挂了,主机挂了,网络挂了…=>心跳包)

网络本身就会存在一些变数.导致tcp连接不能继续正常工作了.
1)进程崩溃
在这里插入图片描述

2)主机关机(正常步骤的关机)
在这里插入图片描述

3)主机掉电(拔电源,没有任何反应的空间)

在这里插入图片描述

4)网线断开
相当于主机掉电的升级版本.
此时A和B就无法通信了.
A这边发生的情况,就是主机掉电的第一种情况
这边发生的情况。就是主机掉电的第二种情况

关于TCP和UDP 对比.

TCP优势在于可靠性适用于绝大部分的场景.
UDP优势在于效率―适合于机房内部的主机之间通信(机房内部,带宽比较充裕,不太容易遇到拥堵丢包的情况。又希望主机之间的通信速度能比较快)

三、网络层

非常复杂的部分
TCP/IP协议栈.
IP协议虽然复杂,但实际开发中涉及到的并不多,不会展开详细讨论.

1.IP协议

IP协议结构

在这里插入图片描述
1)4位版本号,用来表示IP协议的版本.现有的IP协议只有两个版本, lPv4,IPv6

2)4位首部长度.设定和tcp一样.IP报头可变长的.
IP报头又是带有选项的.此处单位也是4字节.

3)8位服务类型.(真正只有4位才有效果)类似于模式/形态切换?
<1>最小延时,传输一个数据报的时间尽量短.
<2>最大吞吐量,一定时间内传输的数据量尽量多.
<3>最高可靠性,在传输过程中最不容易触发丢包.
<4>最小成本,在传输过程中消耗的硬件资源最低.
四种形态是互斥的,只能切换到一种形态.
虽然IP协议支持这个机制,实际上开发中很少会真的使用.一般是系统级别的深度定制化.

4)16位总长度.
IP报头+载荷的长度.
总长度–IP报头长度=>载荷长度=>TCP报文总长度
TCP报文总长度–TCP报头长度=>TCP载荷长度
这里的16位总长度,确实也涉及到64KB的问题.但是IP协议,自身支持"拆包组包"机制.(这里的64KB只是约束了一个IP数据报)
如果需要携带比较长的数据的时候,IP协议会自动的把一个数据报拆成多个数据报.接收方在进行分用的时候,也会把多个数据报合并成一个数据报.

5)16位标识,3位标志位,13位片偏移
描述了整个IP数据报拆包组包的过程.
当IP数据报需要携带比较长的数据的时候,就在IP协议这一层触发拆包操作.把一个大包拆成多个小包.
多个小的IP数据报都会带有IP报头,载荷是TCP数据报的几个部分

在这里插入图片描述
6)8位生存时间TTL单位是次.
初始情况下TTL会有个数值(32/64/ 128)每次经过一个路由器转发,TTL就会–1.减到0了就会被丢弃了.
正常来说TTL足以支持数据报到达网络的任意一个位置.如果确实出现0了,基本可以认为目标IP不可达.

7)8位协议
描述了上层,传输层,使用哪种协议.

8)16位首部校验和
校验数据是否正确的机制.只需要校验首部即可.
载荷部分,要么是TCP要么是UDP,人家自己已经校验过自己了.

  1. 32位源地址,32位目的地址
    IP协议中最最重要的部分.数据报,从哪来,到哪去??

2.IP地址

网络上有这么多主机.需要有办法描述主机的具体位置.IP地址就是解决这个问题的关键.

lPv4:

在这里插入图片描述
[重点]IР地址不够用了咋办??
1.动态分配IP (DHCP)
你这个设备,不会一直需要上网.需要上网,就分配IP,不需要就先不分配。(这种方案,只能缓解,不能根治.)
2.NAT机制(网络地址转换)(理解网络结构的关键要点!!)
IP地址不太够用.想了个办法.把IP地址,分成两大类:
1.内网IP:不同的局域网内的设备,内网ip可以重复。同一个局域网内的设备,内网ip不能重复.
10.*
172.16.*-172.31. *
192.168. *
2.外网IP:外网IP不能重复.
1)如果局域网内部的设备之间进行通信,肯定是ok(局域网内部内网ip都是唯一的).
2)A局域网中的设备,想和B局域网中的设备通信,这个时候咋办??(当前很可能这俩设备的 ip相同)
3)局域网内部的设备访问带有外网IP的设备.
像平时使用的电脑,手机,都是在局域网内部使用.他们会有一个内网IP.还有一类设备,是"服务器",服务器可以有外网IP.
这个过程中,就涉及到NAT工作过程了.在这里插入图片描述
NAT机制下,意义在于说,一个外网IP代表的不一定是一个设备了,而是很多设备!!!
在这里插入图片描述
真实的情况,是我的电脑的数据经过比特路由器,会进行NAT,经过电信光猫,又有NAT,经过电信路由器,又有NAT.(每次经历路由器转发,都"可能"会触发NAT机制)

在这里插入图片描述
在这里插入图片描述

IPv6

从根本上解决IP地址不够用的问题.
lPv4,是4个字节,32位表示IP地址.lPv6,是16个字节,128位,表示IP地址.
lPv6的地址,比IPv4多了多少倍??
在这里插入图片描述

IPv6和IPv4不兼容!!!
要想升级IPv6,就需要更换路由器设备=>花钱(升级IPv6不会提高网速,更不会提高流畅性…)
相比之下,NAT方案,只需要路由器开发商开发出新版本的软件(路由器固件)升级软件,即可直接支持.(成本非常低的)
相比之下,lPv6距离大规模普及,还是有很大的差距的.

国内IPv6进程,是世界领先的!!
在这里插入图片描述

3.IP地址组成

IP地址分为两个部分,网络号和主机号
网络号:标识网段,保证相互连接的两个网段且有不同的标识;
主机号:标识主机,同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号;

1.同一个局域网中设备的网络号必须相同,主机号必须不同.
2.两个相邻的局域网,网络号必须不同

一个IP地址,哪个部分是网络号?哪个部分是主机号?通过子网掩码来识别的.
在这里插入图片描述
在这里插入图片描述
特殊的IP地址
1.将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网;
2.将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包;
3.127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
4.本机环回主要用于本机到本机的网络通信(系统内部为了性能,不会走网络的方式传输),对于开发网络通信的程序(即网络编程)而言,常见的开发方式都是本机到本机的网络通信。

IP协议的另一个重要的功能,路由选择.(数据报在IP协议下是如何进行传输的)
但是路由器,无法做到理解全貌,只能认识部分网络环境(路由器能够知道和它相邻的一些设备的情况)
在这个前提下,进行路由转发,就只能"摸着石头过河"走一步算一步.这里给出的路径,也不一定是最优解,只能说是"较优解"
路由器转发数据的过程,类似于“问路"
在这里插入图片描述

四、数据链路层(越往下,距离程序猿就越远)

代表协议,以太网
以太网这个协议,既涉及到数据链路层的内容也涉及到物理层的内容
o

mac地址

已经有了IP地址,为啥还要有mac地址呢?
历史问题.
IP地址(负责网络层转发),和mac地址(负责数据链路层转发),就被各自独立的设计出来了.
网络层负责的是整体的转发过程.
数据链路层负责的是局部(相邻设备)转发过程.

一般是使用十六进制数字,表示 mac地址的.两个十六进制数字,就是一个字节.
mac地址,是6个字节,表示的范围,比ipv4的地址,大很多.在这里插入图片描述

当前mac地址,都是网卡出厂的时候,就写死了.(可以保证每个设备的网卡都有独立的mac地址的)
因此mac地址也就成了互联网上一种身份标识的方式.

域名解析系统.

上网,要访问服务器,知道服务器的ip 地址.
ip地址,是一串数字,虽然这个数字使用点分十进制已经清晰不少了,但是仍然不方便人们记忆和传播.
使用单词,来代替ip 地址.
在这里插入图片描述
最早的域名解析系统,是一个文件.(hosts文件):每个域名都会对应到一个地址.
但是一旦新的网站出现了,或者旧的网站下线,这里就需要修改.很麻烦。
有大佬专门搞个服务器,把 hosts文件装进去.(大家都以他的为准)
有新的网站注册,也要去这边报备.
有旧的网站注销,也要去这边报备…这个服务器负责更新维护.
咱们在上网的时候,访问某个域名,就都先访问到人家的服务器,把域名对应的ip获取到,就可以进一步的访问目标网站了
在这里插入图片描述
问题:全世界,这么多的主机都在上网,此时DNS服务器能承担这么高的并发量嘛??
两个原则,开源,节流
1.每个电脑上,在进行域名解析的时候,都会有缓存。访问10次搜狗,只有第一次真的访问DNS,后面9次都不一定访问.
2.全世界会搭建出很多的"DNS镜像服务器"(一般是网络运营商或者一些大厂)
<1>从最初的DNS服务器这里同步数据(镜像=>一模一样)
<2>此时访问镜像和访问人家的DNS服务器效果一样,此时就把请求的压力给分摊开了.
在这里插入图片描述
国内大力发展IPv6,也是为了摆脱DNS上的限制.IPv6也需要DNS,是一套新的DNS,和之前的不相关.
中国在IPv6世界领先的行列,在搭建IPv6的DNS的过程中,咱们就有比较大的话语权.

总结

  • 26
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值