标准io和文件io的区别:
- 来源 标准io库 系统调用
- 可移植性 好 不好
- 入口 FILE* fd
- 缓冲区 有 没有
文件类型:7种
b 块设备文件c字符设备文件 d目录文件 -普通文件 l链接文件 s socket文件 p有名管道文件
网络编程是对进程间通信的一个延申-->多台主机间的通信
网络上两台主机之间的通信问题----linux操作系统
工作中用的比较多的是并发服务器模型
网络体系结构
网络设备 = 网络终端设备 + 网络中继(传输)设备
网络体系结构:网络的分层模型和每层所使用的协议集合
两种:OSI 7层 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
TCP/IP 4层 应用层 传输层 网络层 物理层
IP地址---网络地址
定义:在网络中唯一标识一台主机符号就是IP地址
(唯一标识一台主机的符号是MAC地址)
IPV4维护IP地址
4:IP协议版本号是V4 IPV4协议维护的IP地址宽度是4byte=32bit
IPV4协议提供了2^32个IP地址,将地址分为了5类:
A B C D E
C:范围:192.0.0.1---253.255.255.254--->用户IP地址 24网络号+8主机号
unsigned int addr = inet_addr(“127.0.0.1”)----十进制点分形式转为二进制函数
D: 244.0.0.1---239.255.255.254--->组播地址
网络协议
定义:在网络通信中对某种通信规则的约定
分类:
1 网络通用协议(TCP/IP协议族) (已经很完善)
2 行业内部专有协议
3 自定义协议
端口号
作用:用作标识一个应用进程 区分应用进程
是一个非负整数 unisgned int,表示范围:1---65535
1-1023已经被著名的协议占用,用户可用 :1023---65535
进程号:内核用来标示进程的标识符
端口号:写在应用程序内部标识程序的符号
字节序
主机字节序:是不同的CPU主机存贮多字节整数的方式,有大端主机字节序,有小端主机字节序
大端主机字节序:将数据的高字节存放在内存的低地址上
小端主机字节序:将数据的高字节存放在内存的高地址上
注意:由于网络通信中两台主机的字节序有可能不同 ,会造成发送的数据和接收的数据反序,所以在传送网络数据前要做字节适配处理,将多字节整数从主机字节序转换成网络字节序
网络字节序:是大端字节序,用于兼容通信双方的字节序
A: 你好吗?--》适配对方主机字节序
B:?吗好你
主机字节序--->网络字节序
htonl:将4字节的数据的主机字节序转换成网络字节序
htons:将2字节的数据的主机字节序转换成网络字节序
网络字节序-->大端字节序
基于TCP协议网络客户端&服务端模型
服务端:socket-->bind-->listen-->accept-->IO函数(read/write recv/send)
客户端:socket-->connect-->IO函数
fd:非负整数,遵循最小未用原则
0 1 2 输入输出报错。所以fd返回值从3开始
int socket(int domain, int type, int protocol);
作用:创建一个用于通信的网络套接字
参数1:协议域 AF_INET(ipv4协议)
参数2:套接字类型 SOCK_STREAM
参数3:需要的其他协议 0--》自动匹配其他必要协议
返回值:失败 -1
成功 标识socket通道的文件描述符 >3
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
作用:给socket通道绑定网络接收终端
参数1:文件描述符 socket的返回值
参数2:表示本机地址信息的结构体指针
参数3:地址结构体的长度
返回值:0 成功 -1 失败
int listen(int sockfd, int backlog);
作用:监听客户端的连接请求
参数1:文件描述符 socket的返回值
参数2:服务端一次最大监听的客户端个数
返回值:0 成功 -1 失败
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
作用:接收客户端的连接请求
参数1:文件描述符 socket的返回值
参数2:地址信息结构,用来存放接收到的客户端的地址信息
参数3:存放第二个参数大小的变量的地址
返回值:成功 返回新的文件描述符--》标识一个新的socket通道--》用于收发数据
失败 -1
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
作用:接收socket通道中的数据
参数1:新的文件描述符 是accept的返回值
参数2:本地接收buf
参数3:期望接收的字节数
参数4:是否阻塞的接收的标志 0表示阻塞接收
返回值:>0 成功接收到的子节数
-1 失败
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
作用:往socket通道中发送数据
参数1:新的文件描述符 是accept的返回值
参数2:本地发送buf
参数3:期望发送的字节数
参数4:是否阻塞的发送的标志 0表示阻塞发送
返回值:成功 返回发送的字节数
失败 -1
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
作用:连接服务端
参数1:文件描述符 socket的返回值
参数2:目标服务器的主机地址信息结构
参数3:第二个参数的长度
返回值:0 成功 -1 失败
TCP:流式套接字
服务端:
客户端:
三次握手 四次挥手
1.基于UDP协议网络客户端&服务端模型
服务端:socket-->bind-->IO 函数(sendto/recvfrom)
客户端:socket-->IO函数(recvfrom/sendto)
recvfrom()
返回值:成功返回期望接收到的字节数 失败-1
Sendto()
返回值:期望发送的字节数
TCP UDP的区别
- IO模型------->输入输出方式
阻塞IO
若要读的数据没有准备好,或要写入的目标没有空间,将会发生读写阻塞
阻塞函数:
优点:一直等待结果,直到等到结果
缺点:如果等待接受数据的通道坏掉,或文件损坏,那么当前进程会一直被挂起
read()---->死等,非要等到一个结果才返回
Read recv recvfrom write send Accept connect 都是阻塞函数
非阻塞IO
若要读的数据没有准备好,IO函数返回一个约定的错误值,不阻塞当前进程,可以通过循环去多次尝试读取数据。
非阻塞函数
优点:没有读到数据不阻塞当前进程,而是直接返回,带回一个错误值
缺点:多次调用系统调用函数,会带来极大的系统资源开销
IO多路复用
思想:分三步
- 构建一个文件描述符集合表,表的大小是1024bit位,每一个bit表示一个文件描述符所对应的IO通道上是否有数据发生(或者IO通道是否活跃),如果有数据发生,该bit位被置位1,其他bit位被置位0.
- 使用select函数监控指定范围的文件描述符所对应的IO通道是否有数据发生
如果有数据发生,该函数返回通道的个数,并且将文件描述符集合表的相应bit位置位1,同时将其他bit位置位0,如果没有数据发生,那么select函数将阻塞当前进程。
- 对文件描述符集合表中的置位结果做出相应的判断,使用FD_ISSET判断该文件描述符在描述符集合表中是否为1,如果为1,响应这路IO数据,否则不处理。
分析:
1.文件描述符集合表--->文件描述符对应的IO通道是否有数据发生
Fd_set stFdr----1024bit 描述符集合表
2.Select 监控 置位
- 对描述符集合表中的置位情况做判断 0---> fgets 3--->accept 4-->recv/send
服务器模型
- -fgets 3--accept 4--IO函数 recv / send
多线程并发服务器,系统开销小
数据库 sqlite (学会如何使用数据库)
数据库---存放数据的文件
数据:能够输入计算机并能被计算机程序识别和处理的信息集合。
数据库:数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合。
常见的嵌入式数据库:mysql sqlite
Sqlite:是一种小型的嵌入式关系型数据库
sqlite特点:源码开发 代码简洁 免安装 支持SQL语句
对应的源码 sqlite3.c / sqlite3.h
操作数据库的通用指令---->SQL语句
数据库文件
1.创建一张表 指令 表项 约束
2.给表插入内容 指令 表项 值
创建一张表
Create table 表名 (字段表名【各种约束】)
Create table student(id int primary key not null,name text not null,age int not null)
Primary key---->主键约束
- 主键必须唯一,用于标识一条记录,如学生学号
- 主键同时也是一个索引,通过主键查找数据的速度最快
- 主键如果是整型类型,该类的值可以自动增长
Insert---插入表
Insert into 表名(字段列表)values(值列表)
Insert into student (id,name,age) values(1,’zhangsan’,23);
查询表项
Select *from表名--->查询整张表
Select *from表名 where id=n---->条件查询 查询id=n的这条数据记录
删除表里内容
delete from 表名 where 查询条件;
delete from stu where name='wangwu';