网络篇--网络基础
目录
网络的发展
协议
技术标准与行业协议制定机构
协议分层
软件分层的好处
OSI 七层模型
TCP/IP 五层(或四层)模型
再识协议
TCP/IP 协议
为什么要有协议
网络和OS系统的关系
什么是协议
网络传送的基本流程
局域网网络传输流程图
MAC地址
发消息的过程:
跨网络传输流程图
网络中的地址管理-IP地址
Socket 编程预备
理解源 IP 地址和目的 IP 地址
认识端口号
端口号范围划分
socket
传输层
认识 TCP 协议
认识 UDP 协议
网络字节序
socket 编程接口
socket 常见 API
网络的发展
我们计算机是相互独立的,当我们一个团队需要共享资源,但是我们计算分享数据太慢,就想着通过网络来共享资源。
通过一台机器充当我们的服务器。
将我们的多台计算机连接到一起,当我们一个人处理完,推送到我们服务器中,然后另一个再从服务器中拿取。
局域网 LAN: 计算机数量更多了, 通过交换机和路由器连接在一起;
随着我们的局域网越来越多,我们高校之前需要进行学术交流。所以我们不仅需要内部的工程师分享,还需要外部的进行共享。
广域网 WAN: 将远隔千里的计算机都连在一起
协议
协议是以一中约定。
就例如 ,你出去上大学,在早些年,我们打电话是通过座机的,你没有手机,只能借别人的手机打,但是你又不想扣别人的话费,所以你就和你老爸说:电话响一声是保平安,响两声是……。
这个你和你老爸就形成了约定。达成了协议。
计算机之间的传输媒介是光信号和电信号. 通过 "频率" 和 "强弱" 来表示 0 和 1 这样的 信息. 要想传递各种不同的信息, 就需要约定好双方的数据格式.
-
要通信的两台主机, 约定好协议就可以了么?
定好协议,但是你用频率表示 01,我用强弱表示 01,就好比我用中国话,你 用葡萄牙语一样,虽然大家可能遵守的一套通信规则,但是语言不同,即是订好了 基本的协议,也是无法正常通信的
所以,完善的协议,需要更多更细致的规定,并让参与的人都要遵守。
-
计算机生产厂商有很多;
-
计算机操作系统, 也有很多;
-
计算机网络硬件设备, 还是有很多;
如何让这些不同厂商之间生产的计算机能够相互顺畅的通信? 就需要有人站出 来, 约定一个共同的标准, 大家都来遵守, 这就是 网络协议;
我们的每个人的计算机有这么多的不同,也就需要海量公司来帮我们制定协议。一般具有定协议或标准的公司都是业界公认的具有江湖地位的公司。
不仅我们网络有协议,在我们许多硬件也是具有协议的,如我们的网卡、磁盘等。所以在我们计算机中协议无处不在。
技术标准与行业协议制定机构
专注于技术规范、行业标准等协议:
国际标准化组织
如:ISO(国际标准化组织)、IEEE(电气电子工程师协会),制定技术标准协议(如ISO 9001质量管理体系)。
科技巨头与联盟
如:微软、谷歌等参与制定技术协议(如开源协议、API接口标准);区块链领域的Hyperledger联盟制定分布式账本协议。
协议分层
我们在学习我们的操作系统的时候 ,可以知道我们操作系统的整个软硬件体系结构也是分层的
-
软件是分层的,网络协议也是分层的,我们协议本质也是软件,在设计上为了更好的进行模块化,解耦合,也是被设计成为 层状结构的。
我们计算机中,在我们软件工程中,纵向的只有分层,横向的只有模块。
就比如我们写代码,将我们一些功能包装成一个函数,main函数去调用即可。这就是分层。
软件分层的好处
我们上面两人在通话:实际上是你对着你的电话讲,你的电话里面有许多录音设备,将它打包通过移动网络传输到其他设备或服务器。
视角:
-
应用者:同层协议,直接通信
-
工程师:同层协议没有直接通信,是各自使用下层提供的结构能力,完成的通信。
当我们分层的时候,要修改其他的层,并不影响其他层。就比如我们上面不想用电话机打电话,只需要将我们的通信设备换掉即可。这就是可维护性好。
所以:分层就是解耦合的有效方式,可维护性 。便于我们的排查问题和可读性很高。
OSI 七层模型
-
OSI(Open System Interconnection,开放系统互连)七层网络模型称为开放 式系统互联参考模型,是一个逻辑上的定义和规范;
-
把网络从逻辑上分为了 7 层. 每一层都有相关、相对应的物理设备,比如路由 器,交换机;
-
OSI 七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型 的主机实现数据传输;
-
它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚, 理论也比较完整. 通过七个层次化的结构模型使不同的系统不同的网络之间实现可 靠的通讯;
-
但是, 它既复杂又不实用; 所以我们按照 TCP/IP 四层模型来理解.
其实实在网络角度,OSI 定的协议 7 层模型其实非常完善,但是在实际操作的过程 中,会话层、表示层是不可能接入到操作系统中的,所以在工程实践中,最终落地的5层。这种简化不仅降低了实现的复杂性,还能更好地适应实际开发需求,同时保证了网络通信的高效性和稳定性
TCP/IP 五层(或四层)模型
TCP/IP 是一组协议的代名词,它还包括许多协议,组成了 TCP/IP 协议簇.
TCP/IP 通讯协议采用了 5 层的层级结构,每一层都呼叫它的下一层所提供的网络来完 成自己的需求.
-
物理层
作用:
负责在物理媒介(如光纤、电缆、无线电波)上传输原始比特流(0和1),定义电气、机械和时序特性(如电压、接口形状、数据传输速率)。
示例:
-
网线(双绞线、光纤)的接口标准(如RJ45)。
-
无线通信中的调制解调技术(如Wi-Fi的无线电波)。
-
设备:集线器(Hub)(进行信号放大的,使我们的传输规模更远)、中继器(Repeater)。
-
-
数据链路层
作用:
在同一局域网(LAN)内实现可靠的点对点数据传输,将比特流封装成数据帧,并通过MAC地址标识设备。同时处理错误检测(如CRC校验)和流量控制。
示例:
-
以太网协议(Ethernet)。
-
无线局域网协议(Wi-Fi的802.11)。
-
设备:交换机(Switch)、网卡(NIC)。
-
-
网络层
作用:
负责跨网络的路由与寻址,通过IP地址标识设备,并选择最佳路径将数据包从源端传输到目标端。解决异构网络之间的互联问题。
示例:
-
IP协议(IPv4/IPv6)。
-
路由协议(如OSPF、BGP)。
-
设备:路由器(Router)
-
-
传输层
作用:
提供**端到端(进程到进程)**的可靠或不可靠数据传输服务。通过端口号区分不同应用程序,并实现流量控制、错误恢复和拥塞控制。
示例:
-
可靠传输:TCP协议(如网页浏览、文件传输)。
-
不可靠传输:UDP协议(如视频流、DNS查询)。
-
-
应用层
作用:
直接面向用户或应用程序,提供具体的网络服务接口。在五层模型中,应用层整合了OSI模型的会话层、表示层和应用层的功能,包括数据格式转换、加密解密、会话管理等。
示例:
-
HTTP(网页访问)、SMTP(电子邮件)、DNS(域名解析)。
-
加密协议(如TLS/SSL)。
-
数据格式(如JSON、XML)。
-
将我们的上三层压缩成一层。应用层,我们写代码就是基于这一层。
再识协议
TCP/IP 协议
-
TCP/IP 协议的本质是一种解决方案
-
TCP/IP 协议能分层,前提是因为问题们本身能分层
为什么要有协议
我们计算机是一个冯诺依曼结构,我们假设四个人各自抱着自己的计算机去往各地,我们的线是无限延展的,那么我们的计算机体系结构也是网络结构,为什么我们的计算机不需要各种协议呢,因为我们计算机内部的网卡和磁盘的距离很短,
主机A和主机B距离变长了,就会产生其他的问题:
-
主机A需要把信息发给主机C,得先发送给路由器R,(物理层,链路层)
-
网上又有很多主机,怎么准确找到主机C呢,(网络层)
-
数据发出去,丢失怎么办,(传输)
网络通信最大问题是主机距离变远了。所以不同问题有不同的解决方案,就是不同的协议,因为问题是不一样的,所以我们的协议就是分层的。
所以TCP/IP 是我们问题的解决方案。
网络和OS系统的关系
网络是操作系统的一部分。
我们系统的和网络协议栈的结构是对应的。我们LInux和WIndows虽然两台主机不同,但是网络协议栈是相同的,所以是可以进行通信的。
传输层最著名的协议是TCP,网络层最著名的是IP,而我们传输和网络是在我们操作系统中实现的,所以我们操作系统再怎么不同,这个两部分的代码原理是一样的。
我们TCP和IP 是最核心的部分,所以借用此来命名。
我们可以知道,整个协议栈,涉及了硬件、驱动、用户、OS,所以计算机要进行网络通信,是需要IT各行各业的人的配合的。
什么是协议
我们计算机在这个里面也是有各种各样的协议,那OS系统也需要将我们的协议进行管理,:先描述在组织。
我们利用结构体:
struct protocol{
int a ;
int b;
int c;
};
我们的OS是使用C语言写的,TCP IP也是用C语言写的,我们无论是Linux还是Windows网络代码是一样的,结构体类型也是一样的,(在我们的Windows中 有上面的结构体,那Linux也有这个结构体)。
这样二者都具有同样的类型,这不就是进行了约定吗。 所以
-
所谓协议,就是通信双方都认识的结构化的数据类型(结构体就是我们的协议)
网络传送的基本流程
局域网网络传输流程图
局域网(以太网为例)通信原理
-
两台主机在同一个局域网,是否能够直接通信?是的
-
原理类似上课
-
(当我们一群人在教室上课,然后我们的老师质问其中一个同学喊了其名字,问他作业为什么没做完,然后那位同学站起来,其他同学也是能听到的,为什么其他同学没有站起来,因为只教了张三一人,其他人并不是张三,所以并不需要对其作出反应,在这里我们的教室就是我们的局域网,老师和同学进行直接通信,就相当于两台主机同学的名字就是一个唯一的标识自身的地址,所以主机上需要有一个唯一标识自身的地址)。
-
-
每台主机在局域网上,要有唯一的标识来保证主机的唯一性:mac 地址
比如我们两台电脑玩游戏,支持联网也支持单机,将两个电脑放在同一个局域网,两个就能进行通信。
世界上是有很多子网的,在他们内部都是可以进行通信的,
MAC地址
-
MAC 地址用来识别数据链路层中相连的节点;
-
长度为 48 位, 及 6 个字节. 一般用 16 进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
-
在网卡出厂时就确定了, 不能修改. mac 地址通常是唯一的(虚拟机中的 mac 地 址不是真实的 mac 地址, 可能会冲突; 也有些网卡支持用户配置 mac 地址).
发送信息时,会将发送人的MAC地址带上,也会将收信的MAC地址带上,当我们收到消息时 ,所有人都能收到消息
会将自己的MAC地址和消息的接收的MAC地址进行对比,不一样就丢弃掉。
Linux 查看MAC地址命令:ifconfig
发消息的过程:
我们主机判断这个消息是否是发送给自己,是在我们的数据链路层,如果不是,报文丢弃,上层就不会也不会知道,用户就不会知道。
所以局域网通信尤其是以太网,我们在发送消息的时候,只允许一机器发送,一份有效的报文,目标主机才能根据信息进行处理,当我们主机A正在和主机E发,主机B也想发送,就会发生数据干扰,也是数据的碰撞,所以任何一台主机发送消息,就要进行碰撞检测和碰撞避免, 当我们主机A再次发数据包时,发现数据包进行碰撞了(碰撞检测),他就会进行休眠,过一会在进行重发(碰撞避免)。局域网就是碰撞域,
我们所有人都能访问,所以以太网是一种公共资源,在其中发生了数据碰撞,就是数据不一致,但是这不是一个主机内部的,是多主机的,所以在自己发消息的时,阻止不了别人发消息,为了保证数据的可靠性,发生碰撞检测和碰撞避免,本质就是保证以太网的被使用的唯一性。所以我们的以太网就是我们的临界资源,我们的在访问以太网时是互斥的,
-
以太网中,任何时刻,只允许一台机器向网络中发送数据
-
如果有多台同时发送,会发 生数据干扰,我们称之为数据碰撞
-
所有发送数据的主机要进行碰撞检测和碰撞避免
-
没有交换机的情况下,一个以太网就是一个碰撞域
-
局域网通信的过程中,主机对收到的报文确认是否是发给自己的,是通过目标 mac 地址判定
每层都有协议,所以当我进行进行上述传输流程的时候,要进行封装和解包
进行报头就是进行封装。
报文=报头+有效载荷。
报头的共性:
-
报头和有效载荷分离的问题,
-
报头内部,必须包含一个字段,叫做交给上层的谁的字段-----分用。即未来将自己的有效载荷交给谁。
跨网络传输流程图
网络中的地址管理-IP地址
IP 协议有两个版本, IPv4 和 IPv6. 。
-
IP 地址是在 IP 协议中, 用来标识网络中不同主机的地址;
-
对于 IPv4 来说, IP 地址是一个 4 字节, 32 位的整数;
-
我们通常也使用 "点分十进制" 的字符串表示 IP 地址, 例如 192.168.0.1 ; 用点 分割的每一个数字表示一个字节, 范围是 0 - 255;
跨网段的主机的数据传输. 数据从一台计算机到另一台计算机传输过程中要经过一个或 多个路由器
macVSIP
唐僧去往西天取经的路上,要经过很多地方,比如从车迟国到女儿国,女儿国到黑风岭,但是总之唐僧是从东土大唐来的,到西方取经。
在上面:唐僧最终目的地和起始地是固定的,而路过的地方就会变,
-
所以 东土大唐-> 西天 (不变的) 源IP地址->目的IP地址。
-
女儿国->黑风岭, 源MAC地址-》目的MAC地址。
而我们所经过的地方就是路由器。而我女儿国国王怎么去,女儿国国王就是路由算法,怎么去就是查找路由表执行路由算法。
我们查找路由表是根据目的IP进行路由的。
为什么是让我们去黑风岭呢,而不是别的,因为二者离的近,就是我们这个两个属于同一个局域网。局域网通信又需要MAC地址。
-
而MAC地址只在局域网中有效
-
IP几乎不会变化的。
-
Mac 地址一直在变
-
目的 IP 是一种长远目标,Mac 是下一阶段目标,目的 IP 是路径选择的重要依 据,mac 地址是局域网转发的重要依据
我们两个不同的子网想进行通信一定要经过路由器,路由器至少要工作在网络层,路由器也有自己的IP地址,
在A看来,路由器是一台主机,在B看来路由器也是一台主机。
在主机A和B看来,要将我们的数据交给路由器,就是一个局域网通信的过程,
我们路由器要在两个不同的子网中通信,就必须又两个子网的接口,两套不同的驱动程序。
我们主机A先要把我们的消息发送给路由器,(自己的机器也有网络层,也有路由功能,
并且在我们的同一个子网内,IP地址的前缀是一样的,当我们的两个不同的子网进行通信,A主机发送给B主机数据,但是发现二者的IP是如此的不同,这就说明,他们不是同个子网的,就不能进行豫剧网通信,而是要发送给我们的路由器,因为他是这个子网的出口。)
在我们主机A向我们路由器中发送消息时,就是一个简单的封装和解包。
在我们进行通信的过程,不变的是网络层,变的是链路层往下,这样验证了一个观点,同层协议是一样的。
网络层,全网同一层,拿到的报文是一样的,是统一的。
-
IP 网络层存在的意义:提供网络虚拟层,让世界的所有网络都是 IP 网络,屏蔽 最底层网络的差异
Socket 编程预备
理解源 IP 地址和目的 IP 地址
-
IP 在网络中,用来标识主机的唯一性
问题:数据传输到主机是目的吗?不是的。因为数据是给人用 的。比如:聊天是人在聊天,下载是人在下载,浏览网页是人在浏览?
但是人是怎么看到聊天信息的呢?怎么执行下载任务呢?怎么浏览网页信息呢?通过 启动的 qq,迅雷,浏览器。
而启动的 qq,迅雷,浏览器都是进程。换句话说,进程是人在系统中的代表,只要把 数据给进程,人就相当于就拿到了数据。
所以:数据传输到主机不是目的,而是手段。到达主机内部,在交给主机内的进程, 才是目的。
但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标 进程?这就要在网络的背景下,在系统中,标识主机的唯一性
数据在进行网络通信时,本质是 进程(用户)+ 网络(OS)/主机-> 网络(OS )/主机+进程(对端用户)。
认识端口号
-
端口号是一个 2 字节 16 位的整数;
-
端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来 处理;
-
IP 地址 + 端口号能够标识网络上的某一台主机的某一个进程;
-
一个端口号只能被一个进程占用.
我们到达网络层有一个IP地址,告诉我们这是发送给我们的,再向上发送给传输层,传输层必须有一个来告诉我们发送给那个进程,通过端口号;
所以IP地址用来标识主机的唯一性,端口号在主机里面标识进程的唯一性。
IP+端口号,标识某一台主机上的进程。
网络通信的本质:进程通信。
IP+端口->socket。
为什么要有端口号?
我们在系统层面也有标识进程的PID,为什么不用呢?
进程 ID 属于系统概念,技术上也具有唯一性,确实可以用来标识唯一的一个进 程,但是这样做,会让系统进程管理和网络强耦合,实际设计的时候,并没有选择这 样做。
端口号怎么找到进程?
进程在OS内不就是一个个的PCB吗,传输层要根据端口号查找一个进程,就是根据端口号查找PCB吗,所以在我们传输层一定要维护一个端口号的哈希表,端口号就是我们的下标,里面就是我们PCB的地址。
端口号范围划分
-
0 - 1023: 知名端口号, HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的 端口号都是固定的.
-
1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作 系统从这个范围分配的.
理解源端口号和目的端口号
传输层协议(TCP 和 UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 就是在描述 "数据是谁发的, 要发给谁";
socket
-
综上,IP 地址用来标识互联网中唯一的一台主机,port 用来标识该主机上唯一的 一个网络进程
-
IP+Port 就能表示互联网中唯一的一个进程
-
所以,通信的时候,本质是两个互联网进程代表人来进行通信,{srcIp, srcPort,dstIp,dstPort}这样的 4 元组就能标识互联网中唯二的两个进程
-
所以,网络通信的本质,也是进程间通信
-
我们把 ip+port 叫做套接字 socket
传输层
了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核 的,那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来 进行的网络通信。
认识 TCP 协议
TCP(Transmission Control Protocol 传输控制协议).
-
传输层协议
-
有连接
-
可靠传输 (例如:报文传重了,会进行去重,乱序了,会重新排序)
-
面向字节流(怎么读和怎么发没关系)
认识 UDP 协议
UDP(User Datagram Protocol 用户数据报协议)
-
传输层协议
-
无连接
-
不可靠传输
-
面向数据报(怎么读取决于你怎么发)
网络字节序
内存中的多字节数据相对于内存地址有大端和小端之分,网络数据的数据流同样也有大小端之分
当我们跨平台/跨设备数据传输 不同架构的设备可能使用不同的字节序。若未统一,解析数据时会出错。
-
所以通过网络发送数据前,需将主机字节序(若为小端)转换为大端(网络字节序)。
那么如何定义网络数据流的地址呢?
-
发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
-
接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从 低到高的顺序保存;
-
因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高 地址.
-
TCP/IP 协议规定,网络数据流应采用大端字节序,即低地址高字节.
-
不管这台主机是大端机还是小端机, 都会按照这个 TCP/IP 规定的网络字节序来 发送/接收数据;
-
如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即 可;
为使网络程序具有可移植性,使同样的 C 代码在大端和小端计算机上编译后都能正常运 行,可以调用以下库函数做网络字节序和主机字节序的转换
我们的端口号:"192.168.34.45" 是字符串分隔的,但是在我们的进行网络通信的时候 ,是char.char.char.char 4字节IP地址,就是一个结构体中 struct ip{ char p1;char p2;char p3;char p4;};
socket 编程接口
socket 常见 API
C
// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器)
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器)
int bind(int socket, const struct sockaddr address, socklen_t address_len);
// 开始监听 socket (TCP, 服务器)
int listen(int socket, int backlog);
// 接收请求 (TCP, 服务器)
int accept(int socket, struct sockaddr address, socklen_t* address_len);
// 建立连接 (TCP, 客户端)
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
套接字变成,soket的种类会多一些
-
网络socket
-
本地socket(unix域socket)->管道。