网络原理是以理论知识为主
这些理论知识会给咱未来开发起到非常重要的指导意义
应用层(后端开发必知必会)
这一层也有很多现成的协议(后面还会重点介绍HTTP协议,这是做网站必备的)
也有很多时候,是需要程序员自己定义协议
举个外卖平台的例子
网络上传输的数据,本质就是字符串,准确地说,是二进制的"字符串"/"字节串(胡诌的)"
我们是无法直接传输一个"Java对象"这样的内容的,我们必须得按照这种字符串,比如二进制字符串进行传输
Java写代码,都是各种对象,但是在最后发送数据的时候,就需要把对象转成二进制字符串[这个过程我们叫做序列化],或者是转成文本的,都可以,然后当我们收到数据的时候,也需要把(二进制)字符串转换回对象[这个过程我们叫做反序列化],方便处理
实际上,上述这样的格式约定,咋搞都行,可以任意进行约定,只要保证客户端和服务器遵守同一个约定即可
这里再看两个例子
上述方式我们就可以看到,请求和响应,具体的数据组织形式是非常灵活的,程序员想怎么组织都行,只需要保证客户端和服务器这边使用的是相同的规则即可
实际开发中,客户端和服务器往往是两伙人分别开发的,这两伙人配合开发的时候就得保证双方的配合是有效的,这里就需要在开发之前,比如产品经理提出需求之后,就需要客户端和后端开发这俩伙人坐在一起,商量一下这里的数据格式如何确定(具体怎么设定无所谓,但是一定要统一)
然后指定一个人,由这个人整理出一个最终的前后端交互的数据格式规范,然后发一个邮件出来,抄送给客户端和后端这里的相关开发,双方再按照这个规则进行写代码,还会抄送给测试,测试也需要根据这个规范涉及测试用例
等到双方都把代码写完之后,客户端和后端先各自测各自的,双方都测试完之后还要进行联调,把两份代码的程序放到一起,放在一个环境中,试试看能不能正确通信
往往也是客户端和服务器这边的开发,以及测试,都坐在一起配合完成这个工作
总结一下,所有的自定义协议主要就是两方面:
1.明确传递的信息
2.约定好信息按照啥样的格式来组织成(二进制)字符串
虽然我们说,自定义的协议格式是可以任意的,但是网络避免过于天马行空的设计,有些大佬就搞出了一些"通用的协议格式",参考这些格式,就可以对咱们的协议设计产生重要的指导作用
通用的协议格式有很多种体现形式,挑几个重要的介绍一下
1.xml 是以成对的标签来表示"键值对"信息,同时标签支持嵌套,就可以构成更复杂的树形结构数据
优点:xml非常清晰地把结构化数据表示出来了
缺点:表示数据需要引入大量的标签,看起来繁琐,同时也会占用不少的网络带宽,国内最贵的硬件资源就是网络带宽
xml越来越少了,有一些新的方式代替xml,虽然网络传输这里不怎么用了,但是我们后面在其他场景还会用到xml
2.json 可以认为是最流行的一种数据组织格式
本质上也是键值对,但是看起来比xml干净不少
优势:相比于xml,表示的数据简洁了很多,可读性非常好,方便观察中间结果,方便调试问题
劣势:终究是需要花费一定的带宽来传输key的名字
3.protobuffer
谷歌提出的一套,二进制的数据序列化方式
是使用二进制的方式,约定好某几个字节表示哪个属性
最大程度节省空间,不需要传输key了,直接根据位置和长度,区别每个属性
优点:节省带宽,最大化效率
缺点:二进制数据,无法肉眼直接观察,不方便调试,使用起来比较复杂,需要专门编写一个proto文件(这里面有一系列的语法规则),描述数据的格式是咋样的,再进一步通过人家提供的工具,把proto文件转换成一些代码,再嵌入到程序中使用
这个方法主要适用于对于性能要求更高的场景,牺牲了开发效率,换来了运行效率
除了上述的这三种之外,业界还存在很多其他的序列化方式(数据组织格式)
Java标准库就提供了方式
其他第三方库提供的方式就更多了
像HTTP这样的协议,后面重点介绍
传输层
UDP
TCP
UDP基本特点:无连接,不可靠传输,面向数据报,全双工
学习一个协议,当然要掌握协议的特性,还需要理解协议报文格式
UDP协议端格式
其实这个图画的不准确,只是网络排版方便做了妥协
UDP报文长度指的就是载荷具体多长
一个结论,网络传输数据过程中,受到外界干扰,数据可能会出错,因为数据本质上是 光信号/电信号/电磁波,会受到磁场或者高能粒子射线...的干扰,太阳有时候会比较活跃(太阳耀斑),辐射出大量高能粒子,就可能对地球上通信造成影响
可能会导致,本来你要传输的是0,结果变成1,本来要传输的是1,结果变成0,这个过程叫"比特翻转"
所以接收方收到数据之后,就需要先确认一下,这个数据是否是一个错误的数据,校验和就是简单有效的方式
UDP的校验和具体是咋实现的?使用了一直简单粗暴的CRC校验算法(循环冗余校验和),就是把UDP数据报中的每个字节都依次进行累加,然后把累加结果保存到2个字节的变量中,加着加着可能会溢出,但是溢出也无所谓,所有字节都加了一遍(当然不要加上校验和自己),这样就得到了校验和
传输数据的时候,就会把原始数据和校验和一起传递过去,接收方收到数据,同时也收到了发送端送过来的校验和,接收方按照同样的方式再算一遍,得到了新的校验和.如果旧的校验和和新的校验和相同,说明传输过程中数据没出错
1-1024这个范围的端口号,系统赋予了特定的含义,一般也不建议咱们使用,因为这是知名端口号(known port)给一些名气较大的服务器提前安排好了(就像是坐飞机头等舱一样)