网络特点:
1. CS结构
client-客户端 server-服务器 网络中有很多客户端和服务器.
胖服务器,瘦客户机 :服务器功能强大 客户机-功能小
服务器:被动 客户端:主动
2. 分层结构
解决复杂的问题 网络通信就是一个很复杂的问题
学习过程:
1.计算机网络基础理论 --工作用得到的理论
2.基础编程 一对一通信
3.高级编程 一个服务器服务N个客户端 嵌入式用的方式
4.进阶, 高级理论-知道 知其然知其所以然
4.5 数据库
5.在线电子辞典
######## 1.计算机网络基础理论 ###########
网络: 美苏争霸
早起 ARPAnet--> TCP/IP网络
分层结构:
微信app-->OS-->驱动-->网卡--> 网络 -->网卡-->驱动-->os->微信
现今有两种主流的分层方式:
OSI模型: 7层 理论丰满,复杂. 但是没人使用 了解
TCP/IP模型: 4层 简单,实用 普遍在使用 重点
TCP/IP模型:
应用层 application
我们自己写的网络应用程序, 邮件 浏览器 淘宝 微信 .....
传输层 TCP: transport control 层
负责传输的安全性的问题. 数据包:丢失 破坏 乱序
如何保证安全问题.后面讲.
端口号: 16bit,short类型. 0--65535 0-----1023端口号,有一些知名的大厂才能用
1024------5000,预留给大厂,5001----65535
50000以上我们自己用
用于区分同一台设备的内部 app. 每个程序都有一个端口号 port
平时有默认的.
TCP:
面向连接的, 字节流的,安全可靠协议 资源占用大 一对一通信 (进程/线程)
文本,文件,重要信息
UDP:
面向无连接的,数据包的,不安全可靠的协议 资源占用小 一对多通信
A:audio V:vedio
网络层: IP: internet 层
网络寻址的, 负责数据包在网络中如何穿梭的. 作用:将数据包从源头发送到目的地.
IP地址: 32bit,int类型. 寻址的关键.
网络层只负责发送,不负责数据包安全性问题.
IP协议: 后面讲, 实现网络寻址
ICMP: internet control manage protocol 网络控制管理协议
控制和管理 , ping命令 探测对方是否存在
IGMP: internet group manage protocol 网络组播协议,
直播
网络接口层: net interface 层
管理网卡的,接收来自上层(网络层)的消息,选择合适的网卡发出去.
网卡地址: 又称 硬件地址 48bit/6B
每张网卡都有全球唯一的 地址.有个组织负责统一分配.
ARP协议: address rosulation protocol 地址解析协议
已知对方IP,获取对方 网卡地址. IP->MAC网卡地址
为什么需要: 网卡发送数据,只认识网卡地址. 所以需要将对方IP转换为对方网卡地址.
RARP协议: revert ARP 翻转ARP
网卡地址-->IP地址
## 网络拓扑turbo结构##############
交换机: 网络设备扩展用的.
局域网IP:只在局域网内部有效.
我们今天大部分人使用的都是局域网IP.
##### IP地址 ###########
IPv4地址早就分配完了. 总共42亿多个
如何分配: IP地址32bit,分为 网络号+主机号:192.168.124.195---------11000110 10101000 1111100 2 --- 254
分配以网络号 为单位进行.
发现如果给苹果公司一个 A类网络号, 根本用不完.
发现以 A B C类网络,来进行IP分配有严重的浪费问题.
后来引入子网掩码,来区分网络号 A类
B类
C类
D类
E类
针对一个IP地址, 网络号部分全部为1,主机号部分全部为0.
解决方法:
1. 局域网 一个/多个局域网 共享一个 公网IP
2. 子网掩码, 解决分配浪费的问题. 目前无用了.
3. ipv6: 128bit地址 2的128次方------
IP地址表示法:
ip地址,它是一个32bit整数. 但是使用很不方便:为了方便记忆
点分法: 见图 转换为 字符串 "192.168.3.124"
端口号:
port 16bit short类型 . 0--65536
来源: 一台主机 ,内部n个app都要上网.但是 ip地址只能唯一的标示这个主机.
主机如何区分某个app, 端口号
同一台主机,有很多app,他们可能乱用 端口号,导致冲突.
有个组织,负责分配
0-1023 知名软件的端口号
1024-5k 预留的端口号
5k+你的app 就使用他们了.
字节序: byte order 大端和小端 大端: 小端:
那些类型需要转换呢:
多字节类型: 多Byte
char --单字节
char des[] = "hello world";
short int long --多字节
本地/主机字节序--->网络字节序 ip地址:人为点分式
点分式------二进制
short short aa = htons(192.168.124.195) : host to net short
long long aa = htonl(long aa) : host to net long
网络字节序--->本地字节序
short ntohs net to host short
long ntohl net to host long
##### 编程 #@#####
文件操作: open read write close
网络访问: socket recv send close bind listen accept
######## 服务器如何实现 一对多:
1. tcp服务器,使用多线程方式
适合嵌入式产品, 弊端: 当客户端非常多的时候,创建太多线程,就不合适了.
2. udp服务器, 天生就支持一对多
3. 多路复用 ------ IO模型
select()
epoll()
poll()
######### IO模型 ##############
IO:input output 解决 通信 问题.
如何解决通信的通信: 哲学问题
1.阻塞 block
进程recv/accept/read/数据,发现没有消息,等待
大部分函数默认都是阻塞
2.非阻塞 nonblock
进程recv/recvfrom.///..发现没有消息, 不等,而是去做其他事情
一会再过来 看看...
所有的socket fd 默认都是阻塞的.
如何让 socket/fd 变为非阻塞呢.
理论: fd对应os的某个文件. 每个文件内部都拥有一个 u32 flags;
它有32bit, 某位置一表示可写,置零表示不可写.
某位置一表示可读 置零...不可读
其中,有一位 置一表示 非阻塞 ,置零表示阻塞.
我们只需要将 该bit置一即可.
app: 1.获取文件的flags 2.flags |= (1<<x); 3. flags设置回去.
3.异步通知
4.多路复用
服务器如何一对多:
1. tcp服务器,使用多线程方式
适合嵌入式产品, 弊端: 当客户端非常多的时候,创建太多线程,就不合适了.
2. udp服务器, 天生就支持一对多
有的. 如何解决???
服务器使用一个 线程,同时监控 多个客户端.
########### 4.进阶, 高级理论-知道 知其然知其所以然 ##########
1.讲一些 协议, IP TCP UDP ...
了解,理论
以太网头: 源地址 目的地址 IP层数据 校验码
IP层:
一个IP包最大长度 65535B 约等于 65KB.
IP包在网络中有可能会被拆分,然后在目的主机 组合.
生存周期TTL: 一个ip 包,没经过一个路由器TTL会减一.
当TTL为0的时候,会被路由器丢弃.
2.TCP是如何保证安全性的
了解,加深理解
1.应答确认机制:
接收方收到数据,必须对发送方进行应答. 发送方收到应答后才会发送下一次数据.
应答机制使用 序号和确认序号, 可以保证数据准确无误.
2.滑动窗口
接收方可能处理能力很弱,如何协同发送方发送数据呢?
接收方在应答的时候,会在窗口位置写入 下一次可以 接收的大小.
那么发送方 下次会发送小于 窗口大小的数据.
3.超时重发
发送方发送消息后,会启动一个定时器.
如果在指定的时间内没有收到应答,会重发.
4.三次握手 ,四次挥手
握手:建立连接的,connect accept
挥手:断开连接 close close
因为通信是双向的.
一段close,只是关掉一个方向.
另一端需要再次close,关闭另一个方向.
3. 网络配置功能
函数,知道
1) getsockname
获取本地链接的 IP和端口号 ,主要作用 获取本地IP
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd:通信的socket,他已经bind了本地IP端口号
addr: 我们用 struct sockaddr_in 结构.
addrlen: 双向参数, 你要告诉它 你的地址空间有多大.
函数会告诉你真实大小.
返回值:
成功-0
失败 -1,errno
2)杂项函数 这两个函数可以干N多配置工作.
#include <sys/types.h>
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t optlen);
sockfd:代表这个通信连接
level: 功能的大类
optname:功能的小类
optval, 功能需要的参数
optlen: 参数的长度
返回值:
0-success
-1: errno
4. 广播/组播
掌握
广播broadcast : 广播是无法拒绝的,单向的,所有成员都能够收到的.
网络中的广播: 某台主机发送广播包给交换机,交换机识别到广播包
转发给每一个成员.
网络风暴:
广播只存在于局域网中.公网中不允许有广播包出现.
代码使用UDP通信
广播包特点: 广播包的目的地址是 广播地址.
广播地址: 主机号全为1的ip地址,称为广播地址.
交换机收到包,发现 包的目的地址是 广播地址,就会转发给每一个主机.
组播groupcast:
如何唯一的区分一个 "分组"呢??? 每个分组,都有一个 组播IP来标示.
组播IP: 224.0.0.0 --- 239.255.255.255
我们选择 239.1.2.3 来表示我们的 #分组#.
如何给分组发消息呢:
目的地址就是 分组的组播IP即可.