前言
其实本文只是讲解从传输层到应用层实现网络消息传递的一个详细流程,至于更底层的网络层和网络接口层,那就不在我的考虑范围内了,事实上那部分机制是不需要你去操心的,除非你想开发操作系统!
然后本文打着通俗易懂的标题,所以在前言之后我将不会提及任何一个新手可能会不理解的关键字或专业术语(也就是说这样只是方便了理解并不方便使用,但这就是本文的目的,毕竟有了清晰的理解之后无论再换到哪个平台都是同样的使用方式,只不过部分专业术语我可能会在它第一次出现的位置放个【】描述一下它的本名),接下来我将开启典型的情景模式进行讲解。
首先声明,本文主要是根据自己的理解编写而来,如果有错误的地方,不要犹豫,直接打脸就行了。
背景
电脑A和电脑B【服务器和客户端】是相隔了未知距离的两台电脑,有一天,A突然想要跟B打招呼(也许是冥冥之中的命运,他知道了B的存在),这时互联网大哥就出来了(至于这货是怎么诞生的有兴趣的再去查他的生辰吧),A和B都买了一根最新潮的网线【数据传输线】,插在自己身上同时两人都连接到了互联网内。
互联网大哥这时就开始推销了:你想要跟B打招呼吗?拜托我不就成了,A你把要说的话告诉我,然后我再告诉B,同时B要对你说的话我也能反馈给你。
A一听兴奋了,原来打个招呼这么简单,想着他一股脑儿的把自己想说的话通通告诉了互联网大哥,然后......
就没有然后了,互联网大哥跑断了腿也没能找到B住在哪儿,因为A并没有告诉他B的住处,事实上A也不知道B的住处,所以,这场原本预料之中无比轻松欢快的交流宣告破裂。
【任意电脑连接至互联网,便可以通过互联网传输数据,电脑间的资源共享其实就是把一台电脑的资源数据通过互联网传递到另一台电脑,在另一台电脑生成一个一模一样的资源,从而实现了资源共享】
问题来了:怎么找到B的住处?
这天,A在医院陪着断腿的互联网大哥,他们商量着一种可以找到B的住处的方法。
互联网大哥:我们整个互联网家族兄弟姐妹千千万万,B虽然也是委托给了我们家,但我也找不到跟他直接联系的那个人是谁呀,有可能是我千千万万兄弟姐们姨嫂舅伯中的任何一个。
A点着头:对,这确实是个麻烦事,看来我们的首要目的就是要先知道B的住处。
想了一想,这时互联网大哥突然一拍脑门:我想到法子了,我让族里的兄弟姐妹们给每家每户都标个门牌号【IP地址】不就得了,这样的话往后家家户户串门就要容易得多了。
想着,互联网大哥直接从病床上翘了起来,不顾A的拦阻瘸着个断腿就跑出了医院,他迫不及待的想要把这种新潮的想法普及给族里的每个兄弟姐妹,这样的话,他也能帮助A找到B的住处了。
......
也不知道是过了多久以后,这天互联网大哥再次登门到了A家。
A无比热情的迎接了他,饭后互联网大哥递了一张名片给A:这是B家的门牌号。
A接过这张名片,听着互联网大哥给他介绍上面的基本信息:147.258.369.145是他家的门牌号,现在注册门牌号的住户太多,我们分了四个0到255的数再通过符号点连接组成,至于为什么要用点来连接,嘿嘿,这也是我提的方式,毕竟147.258.369.145比147258369145容易识别得多。
听着互联网大哥说完,A算是明白了:那这么说的话往后我把想说的话告诉你,你就能通过这个门牌号传达到B那里去了吗?
互联网大哥点着头:对,而且不只是我,只要是我们家族内的任何一个成员,你把要传递的话告诉他,再把传递的门牌号告诉他,他都能帮你传达消息。
A一听兴奋了,原来打个招呼终于变得这么简单了,想着他一股脑儿的把自己想说的话通通告诉了互联网大哥,然后......
就没有然后了,互联网大哥跑断了腿也没能找到哪个是B,因为B的家族里也有数不清的兄弟姐妹,很明显他也不知道其中哪个是B,所以,这场原本预料之中无比轻松欢快的交流又一次宣告破裂。
【互联网中通过IP地址 + 端口号才能完整的定位到某台电脑的某个程序,从而向该程序发送数据,只依靠IP地址的话不能发送到特定的程序】
问题来了:怎么知道在B的家族中哪个是B?
这天,A陪在医院替互联网大哥削着苹果。
互联网大哥想来想去总觉得这刚施行起来的门牌号机制还是不太完善,不过突然他灵光一闪,又想到了一个极好的法子来改善这个门牌号机制:对呀,我们要是给每家每户的每口人都制定一个身份证【端口号】不就得了,这样通过门牌号和身份证就可以准确的找到B了。
想着,互联网大哥直接从病床上翘了起来,不顾A的拦阻瘸着个断腿就跑出了医院,他迫不及待的想要把这种更新潮的想法普及给族里的每个兄弟姐妹,这样的话,他也能帮助A找到B了。
......
也不知道是过了多久以后,这天互联网大哥再次登门到了A家。
A无比热情的迎接了他,饭后互联网大哥递了一张名片给A:这是B家的门牌号和B的身份证。
A接过这张名片,只见上面写着:147.258.369.145:80,后面这个80的话应该就是B的身份证了。
A说:这样的话往后我把想说的话告诉你,你就能通过这个门牌号和身份证传达到B那里去了吗?
互联网大哥点点头:对。
A一听兴奋了,原来打个招呼终于变得这么简单了,想着他一股脑儿的把自己想说的话通通告诉了互联网大哥,然后......
就没有然后了,互联网大哥虽然把A说的话带到了B那里,但B完全看不明白A在说些什么,因为互联网大哥是用录音机【编码】来记录A的传话的,而他们的录音机只能记录一些正常人完全没法看懂的由数字1和数字0组成的数据【二进制数组】,所以,即便他将A说的话完好无损的用录音机录了下来,但到了B那里时却不知道用什么方式才能播放出来了,所以,这场原本预料之中无比轻松欢快的交流又一次宣告破裂。
【互联网中传递的数据都是由1和0组成的字节数组,任意数据类型(int、string等),任意文件(.mp4、.mp3等)都能转换为字节数组从而在网络中传递,接收方按照传输方的编码方式对字节数组进行转换之后,得到特定的数据类型或文件,这才算是完成了数据的传输】
问题来了:A要传递的话已经到了B的手里,但怎么才能让B看懂A所说的话呢?
这天,A又和互联网大哥聚在一起。
互联网大哥抱怨说:一定是录音机有问题,我要去找生产厂商投诉。
A提议道:找厂商定做一款播放器不就得了,能够把录音机录下来的声音原封不动的回放出来。
听A这一说,互联网大哥一拍脑门:好主意啊,这样的话我们也不用管录音机里装的那些1啊0的是些什么数据了,只管让播放器按照录音机录音的方式【编码方式】进行回放就可以了!
想着,互联网大哥立马就跟A道别离去,也不顾A的挽留,他迫不及待的想要把这种更新潮的想法普及给族里的每个兄弟姐妹,这样的话,他也能帮助B听到A的传话了。
......
也不知道是过了多久以后,这天互联网大哥再次登门到了A家。
A无比热情的迎接了他,饭后互联网大哥介绍了他们最新的传话工具,录音机和播放器。
A一听兴奋了,原来打个招呼终于变得这么简单了,想着他一股脑儿的把自己想说的话通通告诉了互联网大哥,然后......
就没有然后了,互联网大哥虽然把A说的话带到了B那里,但B完全没听明白A在说些什么,因为互联网大哥用录音机同时记录了A说的好几句话。
本来传话的内容是这样的:你好呀!我叫A,我住在A家村!
但播放器播放出来的内容却是这样的:你好呀我叫,A我住,在,A家村!
所以,这场原本预料之中无比轻松欢快的交流又一次宣告破裂。
【因为数据的接收方收到的只是一长串的字节数值,先不论他知不知道该用什么编码方式进行转换,就算知道了,他将数据转换出来以后也只是一段一段分隔开的内容,或是一长串黏在一起的内容,总之他可不知道接收到的这个数据究竟是装了四个int数据呢,还是三个int一个string,还是一张图片】
问题来了:A要传递的话已经到了B的手里,但怎么才能让B理清A要表达的语意呢?
这天,A又和互联网大哥聚在一起。
互联网大哥抱怨说:一定是播放器有问题,我要去找生产厂商投诉。
A提议道:播放器应该没有问题,我想我们可以在传话的内容上做些手脚,比如说,用一些特殊的东西来区分开我说的每一句话,也就是,制定一种规则【传输协议】。
听A这一说,互联网大哥一拍脑门:好主意啊,我想到了一个法子,我们在每句话的前面都加上一个表示你开始说话的词语【消息头】,然后里面记录你这句话说了多少个字【消息头记录的消息体长度】,这样的话就算播放器放出来不是连贯的,但B也能根据我们附加的信息看明白你说的话。
想着,互联网大哥立马就跟A道别离去,也不顾A的挽留,他迫不及待的想要把这种更新潮的想法普及给族里的每个兄弟姐妹,这样的话,他也能帮助B听明白A的传话了。
......
也不知道是过了多久以后,这天互联网大哥再次登门到了A家。
A无比热情的迎接了他,饭后互联网大哥介绍了他们最新的传话规则,以这种规则来传话的话,A说的一句话从播放器放出来大概就是这种格式:
【消息头】A说了一句话,说了三个字【消息体的长度】:【消息体】你好呀!
不过互联网大哥继续说:只不过这种规则的话,为了防止前面的标记(A说了一句话,说了三个字)也被播放器打乱顺序,我们得规定这个标记必须是一个固定的长度,以及一个固定的语法,同时这个长度和语法要让B也知道,这样的话就算传递到B那里时前面的标记被打乱了(比如在B那里是这样:A说了一,句话说了,三个字),但B只要根据我们规定的长度(比如这里是:11)和语法就能整理出这个标记,然后再通过这个标记整理出他后面包含的话,从标记中可以看出后面只有三个字是包含在这句话中的,将这三个字:你好呀,提取出来就是一句完整的话,然后 你好呀 后面跟着的又是下一句话的标记,再根据标记的长度固定为11,筛选出11个字,整理出来就是下一句话的标记,然后根据标记中又可以得出下一句话的长度,以此类推......
A一听兴奋了(虽然他压根就没听明白),原来打个招呼终于变得这么简单了,想着他一股脑儿的把自己想说的话通通告诉了互联网大哥,这次,终于成功了,B终于听到了A对他说的话,虽然内容中有很多不属于原话的标记信息,但B总算是听明白了:
A说了一句话,说了三个字:你好呀!A说了一句话,说了三个字:我叫A,A说了一句话,说了六个字:我住在A家村!
同时,B也通过A的门牌号和身份证并使用这种互联网家族推行的规则向A回应了一声:
B说了一句话,说了三个字:你好呀!B说了一句话,说了六个字:很高兴认识你!
......
至此,这场原本预料之中无比轻松欢快的交流到这里终于轻松欢快的完成了。
互联网大哥为此感到无比的欣慰,虽然只是为A和B解决了看似简单的互相传话,但在这之后,他想到了可以把任何东西都通过一种方式变成很多个1和0组成的数据,然后送到指定的门牌号和身份证的人手里,从而实现了一个无比复杂的物流链,那种最初的和A制定的规则也一直延续了下来。
至此,故事讲完了,如果你还是没听懂或者压根就没看明白讲述了什么,那一定是A和B的描述有问题(A:这锅我不背!B:这锅我不背!),不过,我觉得还是有必要进行总结一下。
总结
总结的话大概就是下面两点:
1、【传输层】两台电脑之间要互通消息的话,通过IP地址和端口号来确定各自的位置,然后将要传递的数据转化为字节数组(因为目前只支持传递这种格式的数据,事实上所有数据存放在内存中都是这种格式),进行相互发送和接收,至于传输层,也是有传输协议的,不过这个一般不需要你去管理,提一下,一般只需要你去关心的就是TCP/IP协议,当然还有UDP/IP协议。
2、【应用层】虽然发送方知道自己发送的是什么东西、转化成字节数组之后有多长,但接收方肯定不知道,所以应用层的网络协议诞生了,他规定发送方和接收方必须使用一个固定长度的消息头,消息头必须使用某种固定的组成,而且消息头里必须记录消息体的长度等一系列信息,以方便接收方能够正确的解析发送方发送的数据。
再次整理一下流程:
发送方发送消息 ->
接收方首先根据协议规定的消息头长度(比如30),取出30个字节 ->
再根据协议规定的消息头编码方式(比如UTF-8),将这30个字节转换为对应数据,也就是得到消息头 ->
再根据协议规定的消息头中的特定位置记录有消息体的长度(比如200),从而在这30个字节之后再取出200个字节 ->
再根据协议规定的消息头中的特定位置记录有消息体的编码方式(比如UTF-8),对这200个字节进行转换,从而得到与发送方发送时一模一样的数据。
所以说,应用层的网络协议,他旨在让你更方便的应用从网络中接收到的数据,至于数据的传递,没有类似http协议的东西,你也可以直接在两台电脑间开干,只不过传来传去就是一堆1和0组成的字节数组,如果你认为能够看得懂,那也就可以不使用协议了。
在unity中的实际应用例子:Unity C# 自定义TCP传输协议以及封包拆包、解决粘包问题
转载请注明出处:http://blog.csdn.net/qq992817263/article/details/56669228