基于linux的高级编程:网络编程

标准io和文件io的区别:

  1. 来源  标准io库  系统调用
  2. 可移植性  好      不好
  3. 入口  FILE*   fd
  4. 缓冲区  有  没有

文件类型: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的区别

 

 

  1. IO模型------->输入输出方式

阻塞IO

若要读的数据没有准备好,或要写入的目标没有空间,将会发生读写阻塞

阻塞函数:

优点:一直等待结果,直到等到结果

缺点:如果等待接受数据的通道坏掉,或文件损坏,那么当前进程会一直被挂起

read()---->死等,非要等到一个结果才返回

Read recv recvfrom write send Accept  connect  都是阻塞函数

非阻塞IO

若要读的数据没有准备好,IO函数返回一个约定的错误值,不阻塞当前进程,可以通过循环去多次尝试读取数据。

非阻塞函数

优点:没有读到数据不阻塞当前进程,而是直接返回,带回一个错误值

缺点:多次调用系统调用函数,会带来极大的系统资源开销

IO多路复用

思想:分三步

  1. 构建一个文件描述符集合表,表的大小是1024bit位,每一个bit表示一个文件描述符所对应的IO通道上是否有数据发生(或者IO通道是否活跃),如果有数据发生,该bit位被置位1,其他bit位被置位0.
  2. 使用select函数监控指定范围的文件描述符所对应的IO通道是否有数据发生

如果有数据发生,该函数返回通道的个数,并且将文件描述符集合表的相应bit位置位1,同时将其他bit位置位0,如果没有数据发生,那么select函数将阻塞当前进程。

  1. 对文件描述符集合表中的置位结果做出相应的判断,使用FD_ISSET判断该文件描述符在描述符集合表中是否为1,如果为1,响应这路IO数据,否则不处理。

分析:

1.文件描述符集合表--->文件描述符对应的IO通道是否有数据发生

Fd_set stFdr----1024bit  描述符集合表

2.Select  监控 置位

  1. 对描述符集合表中的置位情况做判断  0---> fgets  3--->accept  4-->recv/send

服务器模型 

 

  1. -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---->主键约束

  1. 主键必须唯一,用于标识一条记录,如学生学号
  2. 主键同时也是一个索引,通过主键查找数据的速度最快
  3. 主键如果是整型类型,该类的值可以自动增长

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';

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值