Linux网络编程: 网络基础
- 1.网络划分
- 一.网络通信
- 1.网络通信和本地通信的联系
- 2.网络通信与本地通信最本质的区别及其衍生出的问题
- 二.网络协议初识
- 1.为何本地通信不行?
- 2.打电话的例子体会分层模型的好处
- 3.OSI七层模型的提出
- 4.OSI七层模型与TCP/IP五层模型
- 1.TCP/IP与网络协议栈
- 2.OSI
- 三.网络与OS,再次理解网络通信
- 1.网络与OS的关系
- 2.站在系统视角理解网络通信
- 1.理解一下通过网络发送信息
- 2.理解一下通过网络获取信息
- 3.理解一下网络通信
- 四.重新理解协议
- 1.协议报头
- 2.数据包的封装,解包+分用
- 五.局域网与mac地址
- 1.mac地址与局域网通信原理
- 2.局域网通信的数据碰撞问题
- 六.IP地址与端口号
- 1.IP地址
- 2.IP地址与mac地址的区别
- 3.理解IP地址与网络通信
- 1.理解IP地址不变,mac地址一直在变
- 2.理解一下这样做的好处
- 4.端口号
- 1.为何要有端口号
- 2.端口号
- 3.端口号范围划分与知名端口号
- 七.再次理解网络通信与套接字
- 1.网络通信本质就是进程间通信
- 2.理解一下服务端和客户端的IP地址与端口号
- 3.理解每一层的任务
- 2.套接字socket
1.网络划分
计算机网络按照地理覆盖范围的大小,可以将网络划分为局域网(LAN)、城域网(MAN)和广域网(WAN)等几种类型。
局域网:小范围内使用的网络,广域网是大范围内使用的网络(是一种远程网,适合长距离的通信),城域网是覆盖范围介于两者之间的网络
而网络的发展也不是一蹴而就的,网络能够发展:
- 依赖于新的设备的诞生(集线器,网线,光纤,路由器,调制解调器,防火墙…)
- 依赖于三大运营商使用新设备对网络基础设施进行搭建和提供入网方式
- 依赖于互联网公司为用户提供服务从而促进互联网的传播
其中,我们学习过程中更关注前两点
一.网络通信
1.网络通信和本地通信的联系
本地通信就是同一台计算机内部实现的通信,比如我们之前学习的进程间通信,线程间通信(本来就能通信,只不过需要保护临界资源,最经典的模型就是生产者消费者模型)
甚至:
从体系结构角度来看:
进程要打开文件,势必涉及到CPU,内存,磁盘之间的数据交互,而通信的本质就是数据的交互,
因此这一过程也可以看做本机的数据交互,也就是本地通信啊
那么如果本地通信跟网络通信能有什么关联的话,我们学习网络不就能够更加轻松与深刻了吗?
因此我们能够得出:单台机器也是一种网络结构哦,
因此本地通信跟网络通信之间是有一定的联系的,学习过程中我们可以将我们之前学习系统时的部分经验/知识移植到网络当中来,你会发现我们能够很好地理解网络
2.网络通信与本地通信最本质的区别及其衍生出的问题
本地通信和网络通信最本质的区别就是:
网络通信的距离更长
就是这个看似平平无奇的区别,衍生出了一堆问题,而这些问题被很多计算机界的大佬总结归纳为了以下几点:
- 如何做到把数据交给下一跳中转站?(技术问题)
- 在转发过程中,如何进行路径选择,也就是目标主机的定位问题(选择/决策问题)
- 如何保证报文的安全性,处理/防止 报文丢失/出现错误 的问题(传输问题)
- 送达的数据如何才能被使用(应用问题)
针对于这4大问题,网络协议就出现了
二.网络协议初识
所谓协议其实就是一种约定,通信双方通过达成约定就能进行信息传递
1.为何本地通信不行?
命名管道的通信就是由两个进程约定好使用那个管道文件进行通信,你用读方式打开,我用写方式打开,然后我写数据,你读数据,实现进程间通信
共享内存的通信就是我们向OS申请一块内存空间,通过发送特定的信号量或互斥锁来表示某个进程已经完成了对共享内存的写入或读取操作,从而避免数据冲突
消息队列也需要进程间达成某种约定,例如确定使用哪个消息队列、消息的格式和内容等,从而保证数据的指向性传递
它们之间的这些约定本质上就是一种协议,叫做本地通信协议
=============================================================================================
而这只是本地通信,如果现在要进行通信的是两个独立的机器呢?
仅仅通过制定相应的协议就能实现通信吗?
是的,不过协议就没有本地通信这么简单了,需要小到硬件,大到OS,应用程序都需要遵守相应的协议才可以实现网络通信
为何,举一个例子:01序列的划分
计算机的数据可以按照 高低/有无电压、高低/有无电频来划分01序列
磁盘上的数据按照磁性N/S不同来划分01序列
光纤上的数据按照光的强弱/有无来划分01序列
比如如果两个计算机,一个按照磁盘上的N为1,S为0存放数据,另一个按照N为0,S为1存放数据
那么它们交互时发送的数据在二进制上不就完全相反了吗…
因此网络协议就出现了,而网络协议都是分层模型,我们后面会介绍
下面我们用一个例子来理解一下分层模型与网络协议
2.打电话的例子体会分层模型的好处
3.OSI七层模型的提出
但是因为计算机生产厂商很多,OS很多,计算机网络硬件设备很多,因此必定会导致协议混乱,各用各的协议
因此就必须要有人站出来定一个统一的标准,这个人就是OSI组织
OSI(Open System Interconnection,即开放式系统互联)组织提出了OSI七层模型,
但是在工程实践时,发现某些层无法做到彻底分离,所以工程实践中使用的是TCP/IP五层模型
下面我们简单介绍一下
4.OSI七层模型与TCP/IP五层模型
1.TCP/IP与网络协议栈
TCP/IP五层模型是OSI七层模型的一个衍生版本,下面我们先简单看一下OSI七层模型,等到我们学完所有的四层协议之后,我们才能体会到OSI七层模型的完善之处
2.OSI
三.网络与OS,再次理解网络通信
1.网络与OS的关系
所以学习网络时,编写代码跟我们学习Linux系统时编写代码没有什么太大的区别哦
2.站在系统视角理解网络通信
1.理解一下通过网络发送信息
2.理解一下通过网络获取信息
3.理解一下网络通信
我们合到一起
记住这个贯穿顺序哦
四.重新理解协议
1.协议报头
其中:贴快递单就是封装,就是给有效载荷贴报头
撕快递单就是解包+分用,就是去报头拿有效载荷
而这个数据我们称为报文
2.数据包的封装,解包+分用
结合我们刚才谈的网络通信,我们画一下,并且理解一下每一层协议都要做的任务
五.局域网与mac地址
局域网内的所有主机都是使用的同一个通信信道,因此它们是能够直接通信的,但是是会存在数据碰撞问题的
1.mac地址与局域网通信原理
每一个网卡都有一个mac地址(全世界范围内唯一),因此它的主要作用就是来标识具体的网络节点,相当于网络节点的身份证
可以在Linux下使用ifconfig
命令进行查看,ether
后面的就是mac地址,inet
后面的值就是ip地址
在局域网内当设备A想要跟设备B通信时,会先发送一个请求包到整个局域网当中,所有的设备都能够接收到这个请求包
但是只有设备B才会回应设备A,并把自己的mac地址告诉设备A,然后设备A就能够通过设备B的mac地址封装数据包跟设备B进行通信了
mac地址是用来标识局域网当中具体的网络节点,实现局域网当中的通信的
mac地址: 长度为48位, 即6个字节. 一般用16进制数字加上冒号的形式来表示(例如: 08:00:27:03:fb:19)
2.局域网通信的数据碰撞问题
为何会有数据碰撞问题呢?
局域网对于所有主机来说是不是临界资源? 是,好了,不用解释了(跟多线程那里的思路一样)
每个局域网都可以看做一个碰撞域,发生数据碰撞之后,对应的数据会执行碰撞避免算法,也就是各自休眠一段时间,
然后再次发出,直到数据不在碰撞
因此如何避免/解决数据碰撞问题?
任何时刻只允许一台主机在局域网中发送消息,这不就是互斥吗?
六.IP地址与端口号
1.IP地址
我们后面说的IP地址如果没有加特殊说明,一般都是指公网IP
公网IP地址,是用来表示互联网中唯一一台主机的
2.IP地址与mac地址的区别
IP地址是网络通信时源主机,目标主机的唯一标识,mac地址是网络通信时中间所需要经过的设备(也就是数据链路层)的唯一标识
IP地址指明了网络数据包最终要到达的主机地址 -> 就相当于最终目标
mac地址指明了数据包在网络传输过程中当下的目标机器地址 -> 就相当于当下的目标
如果把实现梦想看作一条长路的话:
完成当下目标的目的就是为了实现最终目标,也就是说最终目标让我们选择实现当下目标(这不就是路径选择嘛~~)
3.理解IP地址与网络通信
1.理解IP地址不变,mac地址一直在变
2.理解一下这样做的好处
4.端口号
1.为何要有端口号
现在我们知道: 通过IP地址就能实现跨主机之间的通信了,但是仅仅通过IP地址就能够实现网络通信了吗?
并不是的,打开任务管理器,
我们的计算机会有很多进程并发执行的,我这个计算机收到了一个网络数据,这个数据是浏览器的呢? 还是Xshell的? 还是VS code的? 还是画图板的呢??
也就是说网络通信一定要能够知道数据是给哪一个进程的!!
也就是说数据一定要包含一个能够确定到唯一一个进程的字段
让网络数据给一个进程pid不就行了,这样我不就知道数据要给哪一个进程了吗?
没错,但是发明网络的大佬们没有直接把进程pid拿过来,而是发明了一个新的概念:端口号
2.端口号
端口号(port)是传输层协议当中的一个概念,是一个2字节16位的整数,用来标识唯一的进程(用来标识一个主机上进行通信的不同的应用程序)
而进程pid是OS当中的概念,用来标识唯一的进程,方便OS对进程进行管理
端口号跟进程的关系:
-
一个端口号只能绑定一个进程
(因为端口号是用来标识唯一的进程的,如果一个端口号对应于多个进程,那么传输层将数据往上交付时就不知道该交给哪个进程{也就是应用程序}了) -
一个进程可以绑定多个端口号(比如Web服务器就可以同时监听80端口(用于http通信)和443端口(用于https通信))
-
只有进行网络通信的进程才需要有端口号,不进行网络通信的进程无需端口号
正是出于这样的考虑,所以网络设计者们才新增了端口号这一概念(当然也是为了将网络通信跟进程管理解耦)
因此,我们可以得出一个重要结论:
IP地址 + 端口号能够标识网络上的某一台主机的某一个进程
那么只要有源IP地址,源端口号,目标IP地址,目标端口号,不就能标识网络上的唯二的两个进程了吗!!
补充:
网络通信既能通过tcp进行,也能通过udp进行, 因此在TCP/IP协议中, 用 “源IP”, “源端口号”, “目标IP”,
“目标端口号”, “协议号” 这样一个五元组来标识一个通信
3.端口号范围划分与知名端口号
0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 它们的端口号都是固定的
1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的
有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些固定的端口号:
ssh服务器, 使用22端口
ftp服务器, 使用21端口
telnet服务器, 使用23端口
http服务器, 使用80端口
https服务器, 使用443端口
七.再次理解网络通信与套接字
1.网络通信本质就是进程间通信
IP地址 + 端口号能够标识网络上的某一台主机的某一个进程
比如: 我们打开了一个抖音客户端APP,本质上就是将这个可执行程序加载到内存当中成为进程
我们收到了抖音推送的各种短视频,而且还可以自己制作短视频进行发布
我们收到推送,本质就是抖音服务器上的相应进程向我们发送数据
我们制作短视频并发布,本质就是将我们的数据上传到抖音服务器,也就是将我们的数据发送给抖音服务器上的相应进程
因此,我们就能够很好的理解网络通信的本质就是进程间通信了
2.理解一下服务端和客户端的IP地址与端口号
我们先站在服务端的视角,我要提供服务,那我一定要让客户端知道我的IP地址和端口号,否则客户端联系不到我,我怎么提供服务啊
因此服务端的IP地址和端口号一定是"客户端皆知"的,因此必须是固定的,而且不能轻易改变
然后我们站在客户端的视角,我是用户计算机上面的一个进程,用户可以打开很多进程,而我要想进行网络通信就必须要有自己的端口号
但是如果我这个客户端的端口号也是固定的,那么就会导致各大公司编写客户端时有可能出现端口号的冲突问题
因此
客户端最好/一定不要是固定端口号
而IP地址本来属于用户的计算机的唯一标识,跟着用户的去走即可
(用户的计算机是内网IP,需要经过路由器/网关转为随机分配的公网IP才能进行网络通信,客户端的IP是跟着用户的内网IP走的)
而服务端的IP是公网IP,是固定的
但是客户端一定要能够绑定一个端口号啊,要不然没法进行网络通信的!!
因此当客户端尝试跟服务器建立连接时(tcp协议)或者直接向服务器发送数据时(udp协议),OS会给客户端这个进程随机动态的分配一个端口号(保证该端口号在本机是唯一的),服务器也能够拿到客户端的IP地址和端口号了
至此双方即可开始通信
这一点是我们进行网络编程的前提
3.理解每一层的任务
我们到目前已经见到三个唯一标识了:
端口号,IP地址,mac地址
2.套接字socket
套接字是一个抽象层,它提供了应用程序之间进行网络通信的一个接口,就是OS提供的一个系统调用接口的一个属性
就像是我们要进行文件操作时,需要先打开文件,OS会给我们返回一个文件描述符fd,然后我们操作文件就都是通过fd进行操作
这里也是,我们要进行网络通信时,需要创建套接字,OS会给我们返回一个socket文件描述符的fd,然后我们进行网络通信就都是通过socket_fd进行操作
为何会这样呢? Linux下一切皆文件!!
而且我们可以得出: socket内部必定封装了ip地址和port端口号等等信息
以上就是 Linux网络编程: 网络基础的全部内容,希望能对大家有所帮助!!