Linux - 网络基础概念

目录

1>计算机网络背景

a.网络发展

2>初识协议

a.协议分层

b.OSI七层模型

c.TCP/IP五(或四)层模型

3>再识协议

a.为什么要有TCP/IP协议?

b.什么是TCP/IP协议?

c.TCP/IP协议与操作系统的关系?

d.究竟什么是协议?

4.⽹络传输基本流程

a.局域网网络传输流程图

①局域网通信原理

②认识MAC地址

③数据包封装和分用

b.跨网络传输流程图

[①⽹络中的地址管理 - 认识IP地址](#①⽹络中的地址管理 - 认识IP地址)

5>Socket编程预备

a.理解源IP地址和目的IP地址

b.认识端口号

①端口号范围划分

②理解"端⼝号"和"进程ID"

③理解"源端⼝号"和"⽬的端⼝号"

④理解socket

c.传输层的典型代表

①认识TCP协议

②认识UDP协议

d.网络字节序

e.socket编程接口

①socket常见API

②sockaddr结构

③in_addr结构


1>计算机网络背景

a.网络发展

独⽴模式:计算机之间相互独⽴

⽹络互联:多台计算机连接在⼀起,完成数据共享

局域⽹LAN:计算机数量更多了,通过交换机和路由器连接在⼀起

⼴域⽹WAN:将远隔千⾥的计算机都连在⼀起

所谓 "局域⽹" 和 "⼴域⽹" 只是⼀个相对的概念。⽐如,我们有 "天朝特⾊" 的⼴域⽹,也可以看做⼀个⽐较⼤的局域⽹

计算机是⼈的⼯具,⼈要协同⼯作,注定了⽹络的产⽣是必然的!

2>初识协议

• "协议" 是⼀种约定

计算机之间的传输媒介是光信号和电信号,通过 "频率" 和 "强弱" 来表⽰ 0 和 1 这样的信息。要想传递各种不同的信息,就需要约定好双⽅的数据格式

思考:只要通信的两台主机, 约定好协议就可以了么?

• 定好协议,但是你⽤频率表⽰01,我⽤强弱表⽰01,就好⽐我⽤中国话,你⽤英语⼀样,虽然⼤家可能遵守的⼀套通信规则,但是语⾔不同,即是订好了基本的协议,也是⽆法正常通信的

所以,完善的协议,需要更多更细致的规定,并让参与的⼈都要遵守

• 计算机⽣产⼚商有很多

• 计算机操作系统也有很多

• 计算机⽹络硬件设备还是有很多

• 如何让这些不同⼚商之间⽣产的计算机能够相互顺畅的通信?就需要有⼈站出来,约定⼀个共同的标准,⼤家都来遵守,这就是**⽹络协议**

⼀般具有定制协议或者标准的资格的组织或者公司都必须是业界公认或者具有江湖地位的组织或者公司,比如ISO(国际标准化组织),大家可以通过大模型了解一下,要注意的是它们只生产标准,不写代码实现

a.协议分层

协议本质也是软件,在设计上为了更好的进⾏模块化,解耦合,也是被设计成为层状结构的

软件分层的好处

结论1:两种视角,普通用户视角,工程师视角

结论2:同层之间,在 "直接" 通信

结论3:分层之后,可以无障碍替换任意一层(分层 -> 解耦)
• 在这个例⼦中,我们的"协议"只有两层:语⾔层、通信设备层

• 但是实际的⽹络通信协议,设计的会更加复杂,需要分更多的层

• 但是通过上⾯的简单例⼦,我们是能理解,分层可以实现解耦合,让软件维护的成本更低

b.OSI七层模型

OSIOpen System Interconnection,开放系统互连)七层⽹络模型称为开放式系统互联参考模型,是⼀个逻辑上的定义和规范

• 把⽹络从逻辑上分为了7层,每⼀层都有相关、相对应的物理设备,⽐如路由器、交换机

OSI七层模型是⼀种框架性的设计⽅法,其最主要的功能使就是帮助不同类型的主机实现数据传输

• 它的最⼤优点是将服务、接⼝和协议这三个概念明确地区分开来,概念清楚,理论也⽐较完整。通过七个层次化的结构模型使不同的系统不同的⽹络之间实现可靠的通讯

• 但是,它既复杂⼜不实⽤,所以我们按照TCP/IP四层模型来理解

其实在⽹络⻆度,OSI定的协议7层模型其实⾮常完善,但是在实际操作的过程中,会话层、表⽰层是不可能接⼊到操作系统中的,所以在⼯程实践中,最终落地的是5层协议(后面会解释)

c.TCP/IP五(或四)层模型

TCP/IP是⼀组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇

TCP/IP通讯协议采⽤了5层的层级结构,每⼀层都呼叫它的下⼀层所提供的⽹络来完成⾃⼰的需求

物理层: 负责光/电信号的传递⽅式。⽐如现在以太⽹通⽤的⽹线(双绞线)、早期以太⽹采⽤的的同轴电缆(现在主要⽤于有线电视)、光纤,现在的wifi⽆线⽹使⽤电磁波等都属于物理层的概念。物理层的能⼒决定了最⼤传输速率、传输距离、抗⼲扰性等。集线器(Hub)⼯作在物理层

数据链路层: 负责设备之间的数据帧的传送和识别。例如⽹卡设备的驱动、帧同步(就是说从⽹线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就⾃动重发)、数据差错校验等⼯作。有以太⽹、令牌环⽹, ⽆线LAN等标准。交换机(Switch)⼯作在数据链路层

⽹络层: 负责地址管理和路由选择。例如在IP协议中,通过IP地址来标识⼀台主机,并通过路由表的⽅式规划出两台主机之间的数据传输的线路(路由)。路由器(Router)⼯作在⽹路层

传输层: 负责两台主机之间的数据传输。如传输控制协议 (TCP),能够确保数据可靠的从源主机发送到⽬标主机

应⽤层: 负责应⽤程序间沟通,如简单电⼦邮件传输(SMTP)、⽂件传输协议(FTP)、⽹络远程访问协议(Telnet)等。而我们的⽹络编程主要就是针对应⽤层

物理层考虑的⽐较少,我们只考虑软件相关的内容, 因此很多时候我们直接称为TCP/IP四层模型

⼀般⽽⾔

• 对于⼀台主机,它的操作系统内核实现了从传输层到物理层的内容

• 对于⼀台路由器,它实现了从⽹络层到物理层

• 对于⼀台交换机,它实现了从数据链路层到物理层

• 对于集线器,它只实现了物理层

但是并不绝对,很多交换机也实现了⽹络层的转发,很多路由器也实现了部分传输层的内容(⽐如端⼝转发)

3>再识协议

a.为什么要有TCP/IP协议?

• ⾸先,即便是单机,你的计算机内部,其实都是存在协议的,⽐如:其它设备和内存通信,会有内存协议,其它设备和磁盘通信,会有磁盘相关的协议,⽐如:SATA,IDE,SCSI等。只不过我们感知不到罢了,⽽且这些协议都在本地主机各⾃的硬件中,通信的成本、问题⽐较少

• 其次,⽹络通信最⼤的特点就是主机之间变远了。任何通信特征的变化,⼀定会带来新的问题,有问题就得解决问题,所以需要新的协议!

**本地通信:**所有设备是通过"线"连接起来的,所以计算机内部,冯诺依曼本身就是一个网络结构!

**网络通信:**多态主机通过网络通信,本质也是设备到设备,唯一的区别就是单纯的距离变长了!

之所以要有TCP/IP协议,本质就是通信主机距离变远了!

b.什么是TCP/IP协议?

TCP/IP协议的本质是⼀种网络长距离通信解决⽅案

TCP/IP协议能分层,前提是因为问题们本⾝能分层

c.TCP/IP协议与操作系统的关系?

其实由于我们的体系结构,就注定了网络协议栈是层状的结构!

d.究竟什么是协议?

• 截⽌到⽬前,我们还没接触过任何协议,但是如何朴素的理解协议,我们已经可以试试了

• OS源代码⼀般都是⽤C/C++语⾔写的

问题:主机B能识别data,并且准确提取a=10,b=20,c=30吗?

回答:答案是肯定的!因为双⽅都有同样的结构体类型struct protocol。也就是说,⽤同样的代码实现协议,⽤同样的⾃定义数据类型,天然就具有"共识",能够识别对⽅发来的数据,这不就是约定吗(结构体是协议约定的"计算机式的表达")
• 关于协议的朴素理解:所谓协议,就是通信双⽅都认识的结构化的数据类型!

• 因为协议栈是分层的,所以每层都有双⽅都有协议,同层之间,互相可以认识对⽅的协议!

4.⽹络传输基本流程

a.局域网网络传输流程图

①局域网通信原理

• 两台主机在同⼀个局域⽹,可以直接通信(原理类似上课)

• 每台主机在局域⽹上,要有唯⼀的标识来保证主机的唯⼀性:mac地址

②认识MAC地址

• MAC地址⽤来识别数据链路层中相连的节点

• ⻓度为48⽐特位,即6个字节。⼀般⽤16进制数字加上冒号的形式来表⽰(例如: 08:00:27:03:fb:19)

• 在⽹卡出⼚时就确定了,不能修改。mac地址通常是唯⼀的(虚拟机中的mac地址不是真实的mac地址,可能会冲突,也有些⽹卡⽀持⽤⼾配置mac地址)

• 在windows中,可以使用ipconfig /all指令查看mac地址

• 以太网中,任何时刻,只允许⼀台机器向⽹络中发送数据

• 如果有多台同时发送,会发⽣数据⼲扰,我们称之为数据碰撞

• 所有发送数据的主机要进⾏碰撞检测和碰撞避免

• 没有交换机的情况下,⼀个以太⽹就是⼀个碰撞域

• 局域⽹通信的过程中,主机对收到的报⽂确认是否是发给⾃⼰的,是通过⽬标mac地址判定

• 这⾥可以试着从系统⻆度来理解局域⽹通信原理

初步明⽩了局域⽹通信原理,再来看同⼀个⽹段内的两台主机进⾏发送消息的过程(本质是两个协议栈在通信)

⽽其中每层都有协议,所以当我进⾏进⾏上述传输流程的时候,要进⾏封装和解包

• 对端同层,要先解包,也就是报头和有效载荷进行分离

细节1:(不考虑应用层协议,任何协议)a.报头必须要能做到,和有效载荷进行分离的能力 b.报头中必须包含,如何将自己的有效载荷,交付给上层的那一个具体协议

细节2:底层收到报文,但该报文不是发送给我的,数据链路层直接丢弃

细节3:发送数据类似于入栈,接收数据类似于出栈,所以就称为协议栈
• 为什么要自顶向下封装?因为用户要通过网卡发送数据,所以必须贯穿操作系统,贯穿协议栈,OS是硬件(网卡)的管理者

下⾯我们明确⼀下概念

• 报头部分,就是对应协议层的结构体字段,我们⼀般叫做报头

• 除了报头,剩下的叫做有效载荷

• 即报⽂ = 报头 + 有效载荷

然后,我们再明确⼀下不同层的完整报⽂的叫法

• 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在⽹络层叫做数据报(datagram),在链路层叫做帧(frame)

• 应⽤层数据通过协议栈发到⽹络上时,每层协议都要加上⼀个数据⾸部(header),称为封装(Encapsulation)

• ⾸部信息中包含了⼀些类似于⾸部有多⻓,载荷(payload)有多⻓,上层协议是什么等信息

• 数据封装成帧后发到传输介质上,到达⽬的主机后每层协议再剥掉相应的⾸部,根据⾸部中的 "上层协议字段" 将数据交给对应的上层协议处理

最后,再整体复盘⼀下:

在⽹络传输的过程中,数据不是直接发送给对⽅主机的,⽽是先要⾃顶向下将数据交付给下层协议,最后由底层发送,然后由对⽅主机的底层来进⾏接受,在⾃底向上进⾏向上交付

③数据包封装和分用

下图为数据封装的过程

下图为数据分⽤的过程

我们学习任何协议,都要先宏观上建⽴这样的认识:

  1. 要学习的协议,是如何做到解包的?只有明确了解包,封包也就能理解

  2. 要学习的协议,是如何做到将⾃⼰的有效载荷,交付给上层协议的

b.跨网络传输流程图

①⽹络中的地址管理 - 认识IP地址

IP协议有两个版本,IPv4IPv6。本篇及后面的文章凡是提到IP协议,没有特殊说明的,默认都是指IPv4

IP地址是在IP协议中,⽤来标识⽹络中不同主机的地址

• 对于IPv4来说,IP地址是⼀个4字节,32位的整数

• 我们通常也使⽤ "点分⼗进制" 的字符串表⽰IP地址,例如192.168.0.1,⽤点分割的每⼀个数字表⽰⼀个字节,范围是0 - 255

跨⽹段的主机的数据传输,数据从⼀台计算机到另⼀台计算机传输过程中要经过⼀个或多个路由器

为什么要去⽬标主机,先要⾛路由器?

• 路由器是跨子网通信的必经枢纽,通过解析目标IP的网络标识实现路径选择与数据转发,同时提供网络隔离和安全控制

⽬的IP的意义?

• 目的IP是数据包的终极定位标识,指导路由器跨网络寻址,并联合端口号精准定位目标主机的服务进程

然后结合封装与解包,体现路由器解包和重新封装的特点

对⽐IP地址和mac地址的区别

IP地址在整个路由过程中,⼀直不变(暂时这样理解)

Mac地址⼀直在变

• ⽬的IP是⼀种⻓远⽬标,mac是下⼀阶段⽬标,⽬的IP是路径选择的重要依据,mac地址是局域⽹转发的重要依据

提炼IP⽹络的意义和⽹络通信的宏观流程

IP⽹络层存在的意义:提供⽹络虚拟层,让世界的所有⽹络都是IP⽹络,屏蔽最底层⽹络的差异

5>Socket编程预备

a.理解源IP地址和目的IP地址

IP在⽹络中,⽤来标识主机的唯⼀性

• 后⾯会介绍IP的分类以及IP的特点
• 但是这⾥要思考⼀个问题:数据传输到主机是⽬的吗?不是的,因为数据是给⼈⽤的。⽐如:聊天是⼈在聊天,下载是⼈在下载,浏览⽹⻚是⼈在浏览,但⼈是怎么看到聊天信息的呢?怎么执⾏下载任务呢?怎么浏览⽹⻚信息呢?通过启动的qq,迅雷,浏览器

• ⽽启动的qq,迅雷,浏览器都是进程。换句话说,进程是⼈在系统中的代表,只要把数据给进程,⼈就相当于就拿到了数据

所以,数据传输到主机不是⽬的,⽽是⼿段。到达主机内部,在交给主机内的进程,才是⽬的!

但是系统中,同时会存在⾮常多的进程,当数据到达⽬标主机之后,怎么转发给⽬标进程?这就要在⽹络的背景下,在系统中,标识主机的唯⼀性

b.认识端口号

端⼝号(port)是传输层协议的内容

• 端⼝号是⼀个2字节16位的整数

• 端⼝号⽤来标识⼀个进程,告诉操作系统,当前的这个数据要交给哪⼀个进程来处理

• IP地址 + 端⼝号能够标识⽹络上的某⼀台主机的某⼀个进程

• ⼀个端⼝号只能被⼀个进程占⽤

①端口号范围划分

0 - 1023:知名端⼝号, HTTP, FTP, SSH等这些⼴为使⽤的应⽤层协议,他们的端⼝号都是固定的

1024 - 65535:操作系统动态分配的端⼝号,客⼾端程序的端⼝号,就是由操作系统从这个范围分配的

②理解"端⼝号"和"进程ID"

之前在介绍系统编程的时候,介绍了pid表⽰唯⼀⼀个进程,此处我们的端⼝号也是唯⼀表⽰⼀个进程,那么这两者之间是怎样的关系?

• 进程PID属于系统概念,技术上也具有唯⼀性,确实可以⽤来标识唯⼀的⼀个进程,但是这样做,会让系统进程管理和⽹络强耦合,实际设计的时候,并没有选择这样做

• 另外,⼀个进程可以绑定多个端⼝号,但是⼀个端⼝号不能被多个进程绑定

③理解"源端⼝号"和"⽬的端⼝号"

传输层协议(TCPUDP)的数据段中有两个端⼝号,分别叫做源端⼝号和⽬的端⼝号,就是在描述 "数据是谁发的,要发给谁"

④理解socket

• 综上,IP地址⽤来标识互联⽹中唯⼀的⼀台主机,port⽤来标识该主机上唯⼀的⼀个⽹络进程

IP+Port就能表⽰互联⽹中唯⼀的⼀个进程

• 所以,通信的时候,本质是两个互联⽹进程代表⼈来进⾏通信,{srcIp,srcPort,dstIp,dstPort}这样的4元组就能标识互联⽹中唯⼆的两个进程

• 所以,⽹络通信的本质是进程间通信

• 我们把ip+port叫做套接字socket

c.传输层的典型代表

• 如果我们了解了系统,也了解了⽹络协议栈,我们就会清楚,传输层是属于内核的,那么我们要通过⽹络协议栈进⾏通信,必定调⽤的是传输层提供的系统调⽤,来进⾏的⽹络通信

①认识TCP协议

此处我们先对TCPTransmission Control Protocol传输控制协议)有⼀个直观的认识,后⾯再详细介绍TCP的细节问题

• 传输层协议

• 有连接

• 可靠传输

• ⾯向字节流

②认识UDP协议

此处我们先对UDPUser Datagram Protocol传输控制协议)有⼀个直观的认识,后⾯再详细介绍UDP的细节问题

• 传输层协议

• ⽆连接

• 不可靠传输

• ⾯向数据报

d.网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有⼤端和⼩端之分,磁盘⽂件中的多字节数据相对于⽂件中的偏移地址也有⼤端⼩端之分,⽹络数据流同样有⼤端⼩端之分。那么如何定义⽹络数据流的地址呢?

• 发送主机通常将发送缓冲区中的数据按内存地址从低到⾼的顺序发出

• 接收主机把从⽹络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到⾼的顺序保存

• 因此,⽹络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是⾼地址

TCP/IP协议规定,⽹络数据流应采⽤⼤端字节序,即低地址⾼字节

• 不管这台主机是⼤端机还是⼩端机,都会按照这个TCP/IP规定的⽹络字节序来发送/接收数据

• 如果当前发送主机是⼩端,就需要先将数据转成⼤端,否则就忽略,直接发送即可

为使⽹络程序具有可移植性,使同样的C代码在⼤端和⼩端计算机上编译后都能正常运⾏,可以调⽤以下库函数做⽹络字节序和主机字节序的转换

• 这些函数名很好记,h表⽰hostn表⽰networkl表⽰32位⻓整数,s表⽰16位短整数

• 例如htonl表⽰将32位的⻓整数从主机字节序转换为⽹络字节序,例如将IP地址转换后准备发送

• 如果主机是⼩端字节序,这些函数将参数做相应的⼤⼩端转换然后返回

• 如果主机是⼤端字节序,这些函数不做转换,将参数原封不动地返回

网络规定:所有发送到⽹络上的数据,都必须是⼤端的!

e.socket编程接口

①socket常见API

cpp 复制代码
 // 创建 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); 

②sockaddr结构

socket API是⼀层抽象的⽹络编程接⼝,适⽤于各种底层⽹络协议,如IPv4IPv6,以及后⾯要介绍的UNIX Domain Socket,然⽽,各种⽹络协议的地址格式并不相同

IPv4IPv6的地址格式定义在netinet/in.h中,IPv4地址⽤sockaddr_in结构体表⽰,包括16位地址类型,16位端⼝号和32位IP地址

IPv4IPv6地址类型分别定义为常数AF_INETAF_INET6. 这样,只要取得某种sockaddr结构体的⾸地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容

socket API可以都⽤struct sockaddr *类型表⽰,在使⽤的时候需要强制转化成sockaddr_in,这样的好处是程序的通⽤性,可以接收IPv4, IPv6,以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数

sockaddr 结构

sockaddr_in 结构

虽然socket api的接⼝是sockaddr,但是我们真正在基于IPv4编程时,使⽤的数据结构是sockaddr_in,这个结构⾥主要有三部分信息:地址类型,端⼝号,IP地址

③in_addr结构

in_addr⽤来表⽰⼀个IPv4IP地址,其实就是⼀个32位的整数

本篇文章到这里就结束啦,希望这些内容对大家有所帮助!

下篇文章见,希望大家多多来支持一下!

感谢大家的三连支持!

相关推荐
橘颂TA1 小时前
【Linux】System V 通信——共享内存
linux·运维·服务器·c++
sugar__salt1 小时前
网络编程套接字(二)——TCP
java·网络·网络协议·tcp/ip·java-ee·javaee
程序员果子1 小时前
零拷贝:程序性能加速的终极奥秘
linux·运维·nginx·macos·缓存·centos
请叫我7plus2 小时前
用QEMU进行嵌入式Linux开发
linux·驱动开发·嵌入式硬件
sc.溯琛2 小时前
计算机网络:概论学习1
网络·智能路由器·php
檀越剑指大厂2 小时前
【Linux系列】Linux中的复制与迁移
linux·运维·服务器
Keine Zeit2 小时前
虚拟机Linux(Ubuntu)忘记登录密码
linux·运维·ubuntu
独行soc2 小时前
2025年渗透测试面试题总结-273(题目+回答)
网络·python·安全·web安全·网络安全·渗透测试·安全狮
独行soc2 小时前
2025年渗透测试面试题总结-274(题目+回答)
网络·python·安全·web安全·网络安全·渗透测试·安全狮