网络协议分层与Socket编程详解 - 教程
目录
前言
在当初计算机还只停留在”文件“处理阶段的时候,一切仍看起来井然有序,但随着时代的发展,人们必须通信,需要不断地通过计算机来”获取“信息,以获得人类社会发展的需求,对于”文件“系统的“淳朴”,计算机”网络“的时代便迎面而来。计算机步入网络,便是进入了一个属于计算机更加发光发亮的时代,人们常常说这是大势所趋,计算机属于人类的工具,人类走向它是必然的,为了将计算机这步“棋”下好,便有了计算机网络。
计算机网络背景
网络:计算机是人类的软件,人之间是需要协作的,就注定了计算机之间要进行协作。所以网络的产生是必然的
具体怎么产生的?
从局部到整体。先是产生局部的网络连接,在借助网络将整体连接起来
局域网 LAN: 计算机数量更多了, 通过交换机和路由器连接在一起
广域网 WAN: 将远隔千里的计算机都连在一起
运营商购买通信公司的设备,随后大量建设基础设施,这样就能让更多的人用上网络,当网民数量增多,就产生了互联网公司。
以通信公司作为底子,运营商进行连接搭建网络基础设施,互联网公司作为面子供应网络应用与服务
初识协议
减少通信成本,快速形成共识
协议本质是一种约定
小王为了节省话费,和家里人约定好,手机铃声响一次,代表报平安,响两次,代表没生活费了,响三声代表这通电话是要接的。
计算机之间的传输媒介是光信号和电信号.通过"频率"和"强弱"来表示0和1这样的 信息.要想传递各种不同的信息,就需要约定好双方的数据格式
思考:只要通信的两台主机,约定好协议就能够了么?
- 不可以。尽管我们约定用0与1表示信息,只是我用频率来表示01,你用电信号来表示01,即便我收到了你的信息,我也不知道你在说什么。就好比我用中国话,你 用葡萄牙语一样,即使大家可能遵守的一套通信规则,只是语言不同,即是订好了 基本的协议,也是无法正常通信的
所以,完善的协议,需要更多更细致的规定,并让参与的人都要遵守
计算机生产厂商有很多、计算机操作系统有很多、计算机网络硬件设备有很多,如何让这些不同厂商之间生产的计算机能够相互顺畅的通信?
- 就需要有人站出 来, 约定一个共同的标准,大家都来遵守,这就是网络协议
协议分层
- 协议本质也是软件,在设计上为了更好的进行模块化、解耦合,也是被设计成层状结构的。
所有的软件都是层状,模块化的。
OSI七层模型
OSI(OpenSystemInterconnection,开放系统互连)七层网络模型一个逻辑上的定义和规范就是称为开放 式系统互联参考模型,
把网络从逻辑上分为了7层.每一层都有相关、相对应的物理设备,比如路由器,交换机
OSI七层模型是一种框架性的设计手段,其最主要的功能就是帮助不同类型 的主机建立数据传输
它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚, 理论也比较完整.通过七个层次化的结构模型使不同的架构不同的网络之间实现可靠的通讯
5层协议。就是其实在网络角度,OSI定的协议7层模型其实非常完善,但是在实际操作的过程 中,会话层、表示层是不可能接入到操作系统中的,所以在工程实践中,最终落地的
但是它既复杂又不实用,所以大家按照TCP/IP四层模型来讲解
TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.
TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所献出的网络来完成自己的需求。
TCP/IP五层模型每层分别叫做:
物理层
数据链路层
网络层
传输层
应用层
再识协议
为什么要有TCP/IP协议?
本地通信vs网络通信:
本地通信:所有设备是经过”线“连接起来的。所以计算机内部,冯诺依曼体系本身就是一个网络结构。通信是:设备到设备
网络通信:多台主机,通过网络通信,本质也是设备到设备
这两者唯一的区别:单纯的距离变长了。
距离变长,一定会引发新的问题!!!!
数据丢失了怎么办?
怎么定位目标主机?
怎么处理当下立即要去哪里的问题?
如何处理数据???
有难题,就一定有解决方案:TCP/IP协议
TCP/IP协议本质:是一种网络长距离通信的解决方案
为什么要有TCP/IP协议?:单纯的是因为计算机的通信距离变长了
协议的不同层解决不同性质不同种类的障碍
TCP/IP具体是怎么解决问题的?这些问题具体是什么?
什么是TCP/IP协议?
本质是一种解决方案
TCP/IP能分层本质是因为问题本身能分层
TCP/IP协议与操作系统的关系(宏观上,怎么构建)
网卡驱动中实现数据链路层
OS中实现传输层与网络层
为了应用,所以为了使用以及解决问题,就需要在用户层与OS层之间添加平台调用来调用其他层。就是用户层实现应用层,传输数据的目的
什么是协议?
协议本质:就是约定好的结构体
网络的构成:
多种局域网通信标准+一种广域网通信标准
现在多种局域网通信标准属于广域网通信标准的底层技术
网络传输流程
各种各样的局域网通信标准:
以太网
令牌环网:只有拿到令牌的主机才能向局域网中发消息。就是说,这个令牌就是一个锁
无线LAN
局域网(以太网)通信原理
两台主机在同一个局域网下,是能直接通信的
通信原理类似上课:
它俩不会处理这条消息,只有老师会处理这条消息。就是老师叫张三站起来,李四王五也听到了这话,但是它俩不会处理这条消息,也就是不会站起来,只有张三会站起来。张三又和老师说我要坐下,李四王五也听到了这话,但
也就是说,就算老师对张三说的话其他人都听到了,但在接收到消息后发现不是给自己发送的消息,所以也就不做处理了。如此就是局域网下通信也,当主机a给主机b发消息时,其他主机也会收到消息,但当它们将消息进行分析后发现不是发送给自己的,便不对这条消息做处理了
每台主机在局域网上,都有唯一的标识来保证主机的唯一性:mac地址
认识MAC地址
MAC地址用来识别素材链路层中相连的节点
长度为48位,及6个字节.一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
在网卡出厂时就确定了,不能修改.mac地址通常是唯一的(虚拟机中的mac地 址不是真实的mac地址,可能会冲突;也有些网卡支持用户安装mac地址).
网络传输流程图
网络协议栈每一层都有协议
其实协议报头就代表协议,
协议是什么:结构体
什么:结构体变量就是协议报头
每经过一层就会封装一个报头,除去当前层报头,剩下的叫做“有效载荷”。
数据从上到下在贯穿协议栈的过程,叫做“封装过程”。报文从下到上贯穿协议栈的过程叫做“解包和分用的过程”
当源主机发送报文给目标主机后,对端同层(目标主机对应的协议层)要先解包:报头和有效载荷进行分离
当解包结束后,当前层要将有效载荷交付给上层,这一过程叫做“分用”
细节一:
不考虑应用层,任何协议:
1. 报头必须要能做到和有效载荷进行分离的能力
2. 报头中必须包括如何将自己的有效载荷交付给上一层的哪一个具体的协议
细节二:
底层收到报文,可是该报文不是发给我的,数据链路层直接丢弃
细节三:
协议栈:在进行入栈与出栈就是在对数据进行封装报头和对报文进行解包与分用的时候,其实
对协议栈的每一层都有统一的表述
因此主机a给主机b发送的消息叫做“数据帧”
为什么要自顶向下封装?
- 因为用户在应用层。在两台主机在通信时,实际进行报文发送的是网卡。所以数据就必须要贯穿操作系统,贯穿协议栈。OS是硬件的管理值,网卡也属于硬件
抓包工具:
一般主机接收到不属于自己的消息是,在内容链路层就会将这个报文丢弃,但是网卡存在一种模式“混杂模式”,就是“不管这个报文属不属于我,都把它接收了”。这就是抓包程序的原理
跨网络传输流程图
网络中的地址管理--认识ip地址
ip地址,用来标识全球范围内主机的唯一性(公网ip)
ipv4能表示2^32个ip地址,对于现在而言是远远不够的。所以推出了一个NAT的技术。将ip地址分为内网ip与公网ip,我们平时所接触的的192…的IP地址就是内网ip,内网ip是可以重复利用的但公网ip不行。当我们要访问网络时运营商会拿着我们进入网络时的内网ip带着我们去访问网络,将内网ip转换成公网ip随后返回给运营商,运营商再进行内网转发,转发到我们的计算机中。
ip与MAC地址
ip地址在路由过程中,是不会变的,mac地址一直在变:
- mac地址只在本局域网中有效
报文发送给目标主机后OS看到的只有ip地址,因为mac地址是在数据链路层封装的,经过数据链路层的解包与分用交付给OS后就看不到mac地址了
网络层+ip的本质意义:给网络提供了一层虚拟化层,让世界上所有的网络都叫做:ip网络
当下目标就是ip地址是长远目标,mac地址
长远目标决定路径选择
那能不能不用mac地址,只用ip呢?数据链路层封装的mac地址变成ip地址
每必要。就是可以,从科技角度来说行搭建,但
1. 因为会造成高耦合的情况
2. 缘于计算机网络的发展是从局部到整体的,现有mac地址再有ip地址,如果将mac地址换成ip地址,那么之前在数据链路层使用mac地址的设备都需要进行更新,吃力不讨好
数据在网络的流动
Socket编程
进程是人在系统中的代表,只要把信息给进程,人就相当于拿到了素材
数据传输到主机不是目的,而是手段。到达主机内部,再交给主机内的进程才是目的。
上网,只有两种行为:
从远端服务器获取数据
本地数据,上传到远端服务器
当把数据发送给目标主机后,怎么将数据发送给目标进程呢 ?
- 通过端口号
认识端口号
端口号(port)是传输层协议的内容.
一个2字节16位的整数;就是端口号
端口号用来标识一个进程,告诉操作系统,当前的该数据要交给哪一个进程来 处理;
IP地址+端口号能够标识网络上的某一台主机的某一个进程
一个端口号只能被一个进程占用
端口号可以用来标识平台中唯一的一个网络进程
进程pid也能标识进程的唯一性,那为什么要用端口呢?
不是所有的进程都要进行网络通信的
从技术角度来说,pid是可行的。但是Pid是一个系统的概念,假设pid变化了,网络也要跟着变化。故而不用pid是为了让网络与框架解耦。
p标识全网内唯一的主机,port标识该主机内唯一的进程
ip+port=全网内唯一的一个进程
{源ip+源port代表源主机的源进程;目标Ip+目标port代表目标主机的目标进程}
网络通信的本质:全网内唯二的两个进程在进程间通信。
socket=ip+port
端口号范围
固定的就是0-1023:知名端口号,HTTP,FTP,SSH等这些广为使用的应用层协议,他们的 端口号都
由操作 系统从这个范围分配的.就是1024-65535:操作系统动态分配的端口号.客户端程序的端口号,就
端口号与进程id的关系
- 进程ID属于系统概念,手艺上也具有唯一性,确实可以用来标识唯一的一个进程,但是这样做,会让体系进程管理和网络强耦合,实际设计的时候,并没有选择这样做。
理解源端口号和目的端口号
传输层协议(TCP和UDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号.就是在描述"数据是谁发的,要发给谁";
理解socket
ip是用来标识互联网中唯一的一台主机,port是用来标识该主机上唯一的一个网络进程
IP+port就能表示互联网中唯一的一个进程
网络通信本质:两个互联网进程代表人来进行通信,{srcIp, srcPort,dstIp,dstPort}这样的 4元组就能标识互联网中唯二的两个进程
我们把ip+port叫做套接字socket
传输层的典型代表
传输层是属于内核 的,那么我们要凭借网络协议栈进行通信,必定调用的是传输层提供的平台调用,来 进行的网络通信。
TCP与UDP协议都是囊括在传输层的
认识TCP协议
TCP(Transmission Control Protocol 传输控制协议):
传输层协议
有连接
可靠传输
当出现丢包时,会重新发送报。
- 面向字节流
- 通过比如我向你家水管里灌水,我灌十次水,你能够一次性就接完
认识UDP协议
对UDP(UserDatagramProtocol 用户内容报协议):
传输层协议
无连接
不可靠传输
在传输过程中,允许存在丢包的情况。当丢包时不会重新发送。
- 面向数据报
- 个快递,不会多也不会少;我寄十次快递,你就得拿十次快递。就是比如我给你寄快递,我一次寄十个快递你就得收
既然TCP传输可靠,UDP传输不可靠,那为什么还要用UDP传输呢?
TCP是可靠传输,就说明它会做的工作更多更艰难,且资源占用的也更多。在进行制作时使用TCP协议的话开发周期也会长,可维护性也会降低
UDP是不可靠传输,这也代表它做的工作比TCP少、方便、占用的资源也低。在进行开发时用UDP协议的话开发周期会比用TCP协议的短,且可维护性也会相对高
网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘档案中的 多字节数据相对于记录中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
凡是发送到网络中的内容,必须是大端。如果是小端机发送数据,则必须先转成大端。倘若是小端机接收数据,则在接收时会把数据转成小端
发送主机通常将发送缓冲区中的信息按内存地址从低到高的顺序发出
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从 低到高的顺序保存
因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高 地址.
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来 发送/接收数据;
若是当前发送主机是小端,就必须先将内容转成大端;否则就忽略,直接发送即可;
Socket编程接口
网络通信本质就是:进程间通信
system V---本地进程间通信
posix---网络进程间通信(网络socket)
也支持本地进程间通信(本地socket)
socket会有很多的种类来满足不同的应用场景,所以按理说socket未来的接口会有不同的通信接口规范。但是设计值只想提供一种通信接口既满足本地通信,也满足网络通信
这样以后就直接使用一套接口就行了。
sockaddr与sockaddrin、sockaddrun的关系其实就是继承与多态