linux网络基础
目录
局域网和广域网
初识协议
协议分层
OSI 七层模型
TCP/IP 五层(或四层)模型
再识协议
网络传输基本流程
认识MAC地址
认识IP地址
Socket编程预备
理解IP
理解端口号
理解"端⼝号"和"进程ID"
理解socket
传输层的典型代表
认识TCP协议
认识UDP协议
网络字节序
socket编程接⼝
socket 常⻅API
sockaddr结构
今天我们开始我们的网络学习,话不多说,直接开始。
局域网和广域网
计算机的发展从局部到整体的。
局域网LAN:计算机数量更多了,通过交换机和路由器连接在一起。
广域网WAN:将远隔千里的计算机都连在一起。
计算机是人的工具,人要协同工作,注定了网络的产生是必然的.
初识协议
计算机之间的传输媒介是光信号和电信号.通过"频率"和"强弱"来表示0和1这样的信息.要想传递各种不同的信息,就需要约定好双方的数据格式.
这种格式就是一种约定,我们将协议理解为计算机之间交流的约定。其实就是一套标准。
制定协议的只能是一些权威组织或公司,如:
1.国际标准化组织:
IEEE(电气和电子工程师协会),ISO(国际标准化组织),ITU(国际电信联盟),ETSI(欧洲电信标准学会),ASTAP(亚洲与泛太平洋电信标准化协会)。
2.区域标准化组织:
ETSI(欧洲电信标准学会),ASTAP(亚洲与泛太平洋电信标准化协会)
3.民间国际团体:
IETF(互联网工程师任务组)等。
4.官方机构:
FCC(联邦通信委员会)等。
协议分层
OSI 七层模型
- OSI(OpenSystemInterconnection,开放系统互连)七层网络模型称为开放式系统互联参考模型,是一个逻辑上的定义和规范。
- 把网络从逻辑上分为了7层.每一层都有相关、相对应的物理设备,比如路由 器,交换机;
- OSI七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型 的主机实现数据传输。
- 它的最大优点是将服务、接口和协议这三个概念明确地区分开来,概念清楚, 理论也比较完整.通过七个层次化的结构模型使不同的系统不同的网络之间实现可 靠的通讯;
- 但是,它既复杂又不实用;所以我们按照TCP/IP四层模型来讲解。
TCP/IP 五层(或四层)模型
OSI只是方案,而TCP/IP才是实现方案。
TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完 成自己的需求.
物理层我们考虑的比较少,我们只考虑软件相关的内容.因此很多时候我们直接称为 TCP/IP四层模型。
再识协议
计算机在网络交流的时候,必定会遇到各种各样的问题:
如,A要向C发数据:
会有如下问题:
1.A发数据到C,要先经过路由器,怎么实现?
2.网上这么多主机,怎么找到C?
3.数据发出丢失了怎么办?
4.C怎么知道A发出的数据怎么使用?
而TCP/IP协议就是来解决这些问题的,而至于为什么要分层,是因为这些问题本身会分层。
TCP/IP协议与操作系统的关系(宏观上,怎么实现的):
网络通信本质其实就是两台冯诺依曼体系在“聊天”。
所有的主机上面安装的操作系统可以不同,事实也就是不同,但是所有的主机上面的协议栈必须按照标准进行相同的实现,这就是为什么不同的主机,可以互相通信的秘密。
再深入理解一下:
问题:主机B能识别data,并且准确提取a=10,b=20,c=30吗?
答案是肯定的!因为双⽅都有同样的结构体类型structprotocol。也就是说,⽤同样的代码实现协议,⽤同样的⾃定义数据类型,天然就具有”共识“,能够识别对⽅发来的数 据,这不就是约定吗?
关于协议的朴素理解: 所谓协议,就是通信双⽅都认识的结构化的数据类型 因为协议栈是分层的,所以,每层都有双⽅都有协议,同层之间,互相可以认识对⽅的协议。
网络传输基本流程
认识MAC地址
- MAC地址⽤来识别数据链路层中相连的节点;
- ⻓度为 48 ⽐特位,即 6 个字节.⼀般⽤16 进制数字加上冒号的形式来表⽰(例如: 08:00:27:03:fb:19)
- 在⽹卡出⼚时就确定了,不能修改.mac地址通常是唯⼀的(虚拟机中的mac地址不是真实的mac地址,可能会冲突;也有些⽹卡⽀持⽤⼾配置mac地址).
一个计算机在一个局域网中发数据:
- 以太⽹中,任何时刻,只允许⼀台机器向⽹络中发送数据。
- 如果有多台同时发送,会发⽣数据⼲扰,我们称之为数据碰撞。
- 所有发送数据的主机要进⾏碰撞检测和碰撞避免。
- 没有交换机的情况下,⼀个以太⽹就是⼀个碰撞域
- 局域⽹通信的过程中,主机对收到的报⽂确认是否是发给⾃⼰的,是通过⽬标mac地址判定
初步明⽩了局域⽹通信原理,再来看同⼀个⽹段内的两台主机进⾏发送消息的过程:
⽽其中每层都有协议,所以当我进⾏进⾏上述传输流程的时候,要进⾏封装和解包:
封装的过程其实就是一个入栈过程,而解包和分用其实就是一个出栈的过程。
下⾯我们明确⼀下概念:
- 报头部分,就是对应协议层的结构体字段,我们⼀般叫做报头
- 除了报头,剩下的叫做有效载荷
- 故,报⽂=报头+有效载荷
然后,我们在明确⼀下不同层的完整报⽂的叫法:
- 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在⽹络层叫做数据报 (datagram),在链路层叫做帧(frame).
- 应⽤层数据通过协议栈发到⽹络上时,每层协议都要加上⼀个数据⾸部(header),称为封装 (Encapsulation).
- ⾸部信息中包含了⼀些类似于⾸部有多⻓,载荷(payload)有多⻓,上层协议是什么等信息.
- 数据封装成帧后发到传输介质上,到达⽬的主机后每层协议再剥掉相应的⾸部,根据⾸部中的"上层 协议字段"将数据交给对应的上层协议处理.
最后,在整体复盘⼀下:
在⽹络传输的过程中,数据不是直接发送给对⽅主机的,⽽是先要⾃定向下将数据交付给下层协议, 最后由底层发送,然后由对⽅主机的底层来进⾏接受,在⾃底向上进⾏向上交付,下⾯是⼀张⽰意 图。
认识IP地址
IP 协议有两个版本, IPv4 和 IPv6 .凡是提到IP协议,没有特殊说明的,默认都是指IPv4。
- 对于 IPv4 来说, IP 地址是⼀个 4 字节, 32 位的整数
- 我们通常也使⽤"点分⼗进制"的字符串表⽰ IP 地址,例如192.168.0.1 ⽤点分割的每⼀个数字表⽰⼀个字节,范围是 0-255。
- IP地址是用来标识主机的唯一性
我们来看一个场景:
1.
同一个局域网中,IP地址前缀是相同的,路由器会判断是不是自己局域网中的数据,如果不是推送给路由器,由路由器发送给目标用户。
然后结合封装与解包,体现路由器解包和重新封装的特点:
对⽐IP地址和Mac地址的区别:
- IP地址在整个路由过程中,⼀直不变
- Mac地址⼀直在变
- ⽬的IP是⼀种⻓远⽬标,Mac是下⼀阶段⽬标,⽬的IP是路径选择的重要依据,mac地址是局域⽹ 转发的重要依据
网络通信宏观流程:
IP⽹络层存在的意义:提供⽹络虚拟层,让世界的所有⽹络都是 IP ⽹络,屏蔽最底层⽹络的差异。
Socket编程预备
理解IP
1.
IP 在⽹络中,⽤来标识主机的唯⼀性。
2.
因为人与人之间要通信,换句话说也就是计算机之间通信,更本质的是跨网络的不同计算机中的进程通信,所以网络通信必须要知道和哪台主机通信,然后知道和某台主机的某些进程通信!而IP就是标识主机的。而进程间通信的本质是让不同的进程看到同一份资源,网络间通信看到的同一份资源是网络!
3.
上网,只有两种行为,要么从远端服务器获取数据,要么将本地数据上传到远端服务器。我们所有的网络行为都可以划分成这两类。
理解端口号
端⼝号( port )是传输层协议的内容.
- 端⼝号是⼀个 2 字节 16 位的整数
- 端⼝号⽤来标识⼀个进程,告诉操作系统,当前的这个数据要交给哪⼀个进程来处理
- IP地址+端⼝号能够标识⽹络上的某⼀台主机的某⼀个进程。
- ⼀个端⼝号只能被⼀个进程占⽤
端口号和进程关联起来,可以使用哈希表将进程pid和端口号映射起来!
端口号范围:
- 0 - 1023 :知名端⼝号,HTTP, FTP, SSH 等这些⼴为使⽤的应⽤层协议,他们的端⼝号都是固定的。
- 1024-65535:操作系统动态分配的端⼝号.客⼾端程序的端⼝号,就是由操作系统从这个范 围分配的.
理解"端⼝号"和"进程ID"
我们之前在学习系统编程的时候,学习了 进程.那么这两者之间是怎样的关系?
一个进程可以绑定多个端⼝号;但是⼀个端⼝号不能被多个进程绑定。
进程 PID 属于系统概念,技术上也具有唯⼀性,确实可以⽤来标识唯⼀的⼀个进程,但是这样 做,会让系统进程管理和⽹络强耦合,实际设计的时候,并没有选择这样做。
传输层协议( 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代码在⼤端和⼩端计算机上编译后都能正常运⾏,可以调⽤以下 库函数做⽹络字节序和主机字节序的转换。
socket编程接⼝
socket 常⻅API
sockaddr结构
socket API是⼀层抽象的⽹络编程接⼝,适⽤于各种底层⽹络协议,如IPv4、IPv6,以及后⾯要讲的UNIX DomainSocket.然⽽,各种⽹络协议的地址格式并不相同。
- IPv4和IPv6的地址格式定义在netinet/in.h中,IPv4地址⽤sockaddr_in结构体表⽰,包括16位地址 类型,16位端⼝号和32位IP地址.
- IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6.这样,只要取得某种sockaddr结构体的 ⾸地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的 内容.
- socketAPI可以都⽤structsockaddr*类型表⽰,在使⽤的时候需要强制转化成sockaddr_in;这样 的好处是程序的通⽤性,可以接收IPv4,IPv6,以及UNIXDomainSocket各种类型的sockaddr结构 体指针做为参数;
sockaddr结构体
sockaddr_in 结构体
虽然socketapi的接⼝是sockaddr,但是我们真正在基于IPv4编程时,使⽤的数据结构是sockaddr_in; 这个结构⾥主要有三部分信息:地址类型,端⼝号,IP地址。
in_addr结构体(其实就是32位的整数,存放着IP地址信息)
in_addr⽤来表⽰⼀个IPv4的IP地址.其实就是⼀个32位的整数。
接口:
socket函数:创建套接字
bind函数:绑定端口号,IP
sockaddr_in结构体里面存放着端口号,IP地址和地址族(协议类型)
recvfrom函数:接收消息
sendto函数:发送消息
我们下期见!!!