网络发展历史和分层
最早的"阿帕网" 采用的是网络控制协议, 这个协议跟现在的互联网是有相同的地址, 比如说它能够互联, 不同种类的计算机, 和不同的操作系统, .我们的互联网也是同样道理的.,但是没有纠错功能., TCP发送的时候不会出错
TCP可靠传输 IP不可靠传输(实现电脑互联)
Linux系统中有一千多万行代码, 其中有一百多万行代码是跟网络有关系的.??
TCP/IP 协议采用了分层的思想 .
网络采用分层的思想:
1.每一层实现不同的功能,对上层的数据做透明传输(也就是你上面的数据对我来说,我不管你是什么东西, 我就直接把你处理, 处理完了提供给下层)
2.每一层向上层提供服务,同时使用下层提供的服务
基于这种思想出现了两种模型,
OSI 模型是一种理论模型, 到目前还没有一个完整的实现
三层交换机是偏软件的
二层交换机是偏硬件的
工业标准 也是用的最多的四层模型,
可靠传输和不可靠传输 没有好坏之分, 看你应用在什么场景,
Linux系统它在跑的要么是用户的进程,或者是线程,或者内核这三种, 它都是很多任务在那边跑, 假设我手机这边要给pc这边发个数据过去, (Linux多任务系统)数据发过来之后,到底是发送给Linux里的哪个任务呢 ?也就是发给哪个进程, 哪个线程呢 ? 那么这个就是通过传输层来实现的, 数据应该交给哪一个任务来处理 这个就是由传输层来实现的。
应用层 : FTP 是文件传输 , SMTP 收发邮件的
网络接口与物理层
MAC地址 : 48位数 全球唯一, 标识网卡, 网络设备身份标识
ARP/RARP :
一个数据包从一边发到另一边的时候, 数据包发过去的时候, 发送的时候上层说发给某个IP地址,那么真正的在物理层面上面或者在硬件层面上面这个数据包经过底下的网络接口物理层网卡或者无线, 硬件的东西,通过它发送的时候, 就会由MAC地址, MAC和IP地址是怎么对应的, 就是通过ARP和RARP来定义的,这个
ARP : 就是通过(叫地址解析协议)主要是把IP地址通过IP地址找到对应的MAC地址
RARP : 通过MAC地址找到 IP地址
PPP协议 : 拨号协议
以前的电话机拨号, 电话线上网, 后面慢慢发展成(GPS,3G,4G) 只是现在的线是无线的
网络层 :
IP协议 :
IP : Internet protocol(分为IPV4 和 IPV6)什么叫IPV4 ? 什么叫IPV6 ?
比如说经常看到的我这个网卡192.168多少多少的就是IPV4的,另外一种呢,fe80::250:56ff:fe27:3610以冒号分隔的
ICMP:internet 控制管理协议 ,ping命令属于ICMP (网络层)
IGMP:internet 分组管理协议,广播,组播
传输层:
TCP : 面向连接的 ,就是我这台机器要跟另一台机器通信 ,TCP通信的就是面向连接 要建立连接,就像打电话一样,我要给你打电话呢 ? 我要给你拨号, 拨 号的过程在我们这个交换机里面,它就会建立一个虚拟的一个连接形成一个链路,这样子的话我打电话的时候,我打给你就不会跟别人串线, 或者我打的时候别人是不能接听电话的 。一对一的,并且是可靠传输。怎么做到可靠的, 是消耗一定的资源来完成的。
硬件传输的时候有可能出现丢包这类的, 这是不可靠的,
UDP : 数据报协议, 不可靠,无连接的一种传输,
.UDP
NTP 现在的手机就是采用这个,同步网络准确时间 , 以前的诺基亚手机当手机电池拔掉以后,时间就不准确了
SNMP 协议挺重要
应用层处于传输层之上的, 它的数据包都要通过传输层来实现, 传输层里面有两种一种是建立连接的一种是不建立连接的, TCP 和 UDP 而这个RTP/RTSP这个要实时的传输一个音视频和控制 的这个协议是通过TCP + UDP来实现的。
从上面的图可以看到,网络是通过各级的路由器传输。 就是在互联网上面你可以想象成一堆的路由器。 电脑A传给电脑B都是通过网络的路由器数据传输的。另外在传输的时候, 这个数据本身要跨不同的机器,跨不同的操作系统,在这个数据里面是怎么处理的呢 ?处理的过程之间叫做网络的封包和网络的拆包。
同时网络接口物理层介于软件层面上的东西,网络接口物理层通过驱动的一些机制把数据包送到底层的硬件上面,送到硬件上的以太网上面或者硬件上面的wifi上面,硬件会在数据包后面加上一个CRC认证,这样的话就组成了完整的包,然后通过以太网驱动就可以通过网络的方式把它送到路由器A,网络上面都是各级路由器,路由器传输的时候它可能会有自己的网,可能是光纤网络啊,或者是令牌环网啊,通过它传输的时候, 这个以太网头部或者wifi头部就会被它替换掉,然后就一步一步的发送到客户端 。
客户端收到以后,硬件收到了,硬件收到以后一般放在内存里面,硬件网卡会有一个外部,在通过一些机制内核里的驱动机制把这些数据包都送到我们的驱动里面来, 收到驱动里面来我们就会把,网络接口物理层把以太网头部拆掉,完了之后再送到网络层,网络层把IP头拆掉, 再送到传输层 把TCP头拆掉,再通过socket编程,就到应用层了,应用层就拿到一个数据包data。所以我们可以看到真正的目的是传输数据包data,但是为了传输这个data会采用一些协议比如TCP协议为了保证可靠传输,加上一些包头这些东西,IP保证硬件传输,
下图以 以太网的为例,
Socket是一个应用编程接口, 在应用层里面
原始套接字 : 穿透了, 跨过了传输层, 直接到网络层 . 前面提过ICMP这个协议有一个典型的命令 叫 ping命令, 你当ping的时候实际上在应用层这边起的作用 , ping的这个命令的协议采用ICMP, 它在执行的时候是直接从应用层这边直接到内核里面的网络层,它中间跳过了传输层, ping命令去ping一个机器到另一台机器的时候 ,没有经过传输层,简单的说就说它没有TCP或UDP的包而是采用ICMP的包 .
原始套接字 实际上就不是唯一对应 , 而是对应着多个协议 , 同时传输的时候跨过了传输层
IP地址 : 你在软件层面 , 网络层里面,一台机器发送数据包到另外一台机器的时候 ,它的这个地址就是IP地址,
IP地址分为IPV4 和 IPV6
IPV4:采用32位整数来表示 ,地址不够用来, 主要解决方法就是采用局域网, 缓解IP地址不够用问题,
IPV6 : 采用了128位的整数来表示 , 从数字来看比IPV4扩大了四倍, 实际上不是, (地球上的每一粒沙子都会有IP) , 如果全采用IPV6的话 就不需要局域网了,
moblieIPV6 : 移动的, 如果真正的网络实现IPV6的话 那么实际上大家都会有一个场景 , 类似于局域网里的一个概念, 你从深圳坐高铁到武汉, 这个iP整个链接或者通话之类的都可以走一个网络, 不需要像现在走联通和基站 .,
local IP(本地注册的IP) roam IP(漫游IP)
IPV4 两种表现形式 :
点分形式 : 192.168.7.246
32位整数 : 计算机在网络里面传输的时候它采用的是整数的方式,
特殊IP地址 :
局域网IP :192.XXX.XXX.XXX 10.XXX.XXX.XXX
广播IP : xxx.xxx.xxx.255 255.255.255.255(全网广播)
组播IP : 224.xxx.xxx.xxx 开始 ~ 239.xxx.xxx.xxx 结束 这中间要把广播的ip地址取消掉不以 255 结尾
IP地址属于网络层 : 实现的把一台机器数据发到另外一台机器
端口号 : 交给哪个任务来处理
TCP端口和UDP端口是相互不干扰的 : TCP在用5005端口, UDP也可以用5005端口 ,是不干扰的因为,内核中处理的路径不同,
网络编程: 两个部分 1. 硬编程 , 2. 网卡驱动相关东西, 其他都是内核提供的相关东西 ,
字节序是指不同的CPU访问内存中的多字节数据的时候, 存在大小端问题(字节序问题)
假如有个数据0x12345678 十六进制数, 如果按照我们的 如果按十进制来看的话, 就是个十百千万… 这个个位就是我们的低端 , 十六进制也是这样的道理, 最高位是高端 1, 最低位是低端 8 . 那在我们内存里面CPU去访问它的时候,就存在两种可能性 , 在存储的时候是在内存中怎么存储的呢 ? 两种可能性 第一种 12 34 56 78 第二种 78 56 34 12 ,
网络传输的时候最早采用的是大端模式 , 大小端模式对我们网络来说具有比较重要的意义,因为网络传输里面经常会跨机器, 跨操作系统这些概念, 它经过了很多路由器之后,那么这个数据到底是大端还是小端模式就要统一,就像网络里面采用大端要统一, 让大家都能够去理解到这个网络你到底是在传什么数据 , 为了实现这个又引入了一个概念叫本地字节序和网络字节序.
网络通信的概念 : 通信的时候 有IP地址 有端口号 , 通信的时候本地转网络字节序, 网络转本地字节序. (除字符串外)
下图如果只是字符串(单字节)的话,那就不用转,可以直接发送到B机器上去
网络传输无非就是 本地转网络, 网络转本地
系统还给我提供了一些跟IP地址相关的函数 , 提供IP地址转换问题
IP地址转换函数:
in_addr_t inet_addr(const char *cp);
cp: 点分形式的IP地址 , 结果是32位整数(内部包含了字节序的转换了 , 默认是网络字节序模式)
特点 : 1.仅适用于IPV4的情况
2.当出错的时候 ,返回 -1 成功返回 1
3.此函数不能用于 255.255.255.255的转换 (原因 : 转出来之后全是1跟我们的-1的存储实际上是一样的. 到最后分不清楚是4个255转出来的东西还是系统出错返回的数据)
inet_pton() / inet_ntop()
inet_pton()
特点 : 1.适应于IPV4 和 IPV6
2.能正确处理 255.255.255.255的转换问题
参数:
1.af :地址协议族(AF_INET(IPV4)或AF_INET6(IPV6))
2.src : 被转换之前的这个值, 是一种指针(填写点分形式的IP地址[主要指IPV4])
3.dst : 是一个void指针 . 转换的结果给到dst 返回到上一个调用这个函数的里面去 注意:这个要的是地址
成功的时候返回 1, ,如果没有一个有效的字符串地址 就返回 0 ,其他错误返回 -1
inet_ntop() 把IPV4/IPV6的网络字节序的地址变成本地的字符串形式的IP地址
特点 : 1.适应于IPV4 和 IPV6
2.能正确处理 -1的转换问题
参数:
1.af :地址协议族(AF_INET(IPV4)或AF_INET6(IPV6))
2.src : 被转换之前的这个值, 是一种指针(填写的是32位网络字节序的IP地址)
3.dst : 输出结果为点分形式的IP地址[主要指IPV4]
4.size : 是点分形式地址的长度
成功的时候返回非NULL指针, ,错误返回NULL