当前位置: 首页 > wzjs >正文

做网站的公司都有哪些焦作网络推广哪家好

做网站的公司都有哪些,焦作网络推广哪家好,电脑页游排行榜前十名,鹤壁网站建设鹤壁1.本地套接字介绍 c 本地套接字是进程间通信的一种实现方式: - 管道: 有名管道, 匿名管道 -> 简单, 推荐使用 - 内存映射区 -> 不阻塞 - 信号 -> 携带的信息量少, 并且信号优先级太高, 打乱程序的执行顺序 -> 不推荐 - 本地套接字 -> 基于…

1.本地套接字介绍

``c
本地套接字是进程间通信的一种实现方式:
    - 管道: 有名管道, 匿名管道   -> 简单, 推荐使用
    - 内存映射区 -> 不阻塞
    - 信号    -> 携带的信息量少, 并且信号优先级太高, 打乱程序的执行顺序 -> 不推荐
    - 本地套接字 -> 基于网络套接字来实现的
        - 程序实现比较复杂
    - 共享内存   -> 项目1中会用, 效率很高, 但是也不阻塞
    - 消息队列    -> 没讲

本地套接字实现方式:
    - 基于tcp实现 -> 推荐
        - 不需要使用IP和端口, 需要使用套接字文件
        - 套接字文件中不存储数据(类似于有名管道文件)
            - 数据在内核的某块内存中存储着, 套接字文件关联着内核中的内存
            - 通过文件描述符就可以对内核的内存进行读写了
    - 基于udp实现
```

2.本地套接字服务器端通信流程

3.本地套接字客户端通信流程

- 结构体

  ```c
  // 头文件:  sys/un.h
  #include <sys/un.h> 
  #define UNIX_PATH_MAX 108
  struct sockaddr_un {
      sa_family_t sun_family;         // AF_UNIX, AF_LOCAL
      char sun_path[UNIX_PATH_MAX];    // 套接字文件的路径(绝对/相对)
  };
  ```

- 通信流程 - 基于tcp

4.本地套接字客户端和服务器代码

- 服务器端
  
    ```c
    // 1. 创建监听的套接字(文件描述符)
    int lfd = socket(AF_UNIX, SOCK_STREAM, 0);
        - 第一个参数使用: AF_UNIX 或者 AF_LOCAL
        - 第二个参数: 基于tcp使用: SOCK_STREAM, 基于udp使用: SOCK_DGRAM
        - 第三个参数: 0
    // 2. 监听的套接字和本地的套接字文件绑定
    //        本地套接字文件不需要程序猿创建, 绑定成功会自动生成
    struct sockaddr_un addr;
    bind(lfd, (struct sockaddr*)&addr, sizeof(addr));
    // 3. 设置监听
    listen();
    // 4. 等待并接受连接
    //         第二个参数传出的是客户端进程绑定的套接字文件的地址
    accept(lfd, (struct sockaddr*)&cliaddr, &len);
    // 5. 通信
    接收数据: read/recv
    发送数据: write/send
        
    // 6. 断开连接, 关闭文件描述符
    close();
    ```

5.本地套接字测试-bug修改

- 客户端
  
    ```c
    // 1. 创建通信的套接字(文件描述符)
    int fd = socket(AF_UNIX, SOCK_STREAM, 0);
        - 第一个参数使用: AF_UNIX 或者 AF_LOCAL
        - 第二个参数: 基于tcp使用: SOCK_STREAM, 基于udp使用: SOCK_DGRAM
        - 第三个参数: 0
    // 2. 通信的套接字和本地的套接字文件绑定 -> 客户端进程也需要一个套接字文件
    //        本地套接字文件不需要程序猿创建, 绑定成功会自动生成
    struct sockaddr_un addr;
    bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    // 3. 连接服务器进程
    struct sockaddr_un seraddr;    // 初始化服务器绑定的套接字文件
    connect(fd, (struct sockaddr*)&seraddr, sizeof(seraddr));

6.进程间通信的场景

  // 4. 通信
    接收数据: read/recv
    发送数据: write/send
        
    // 5. 断开连接, 关闭文件描述符
    close();

7.libevent特点介绍

- 特点 

  > Libevent 是一个用C语言编写的、轻量级的开源高性能事件的框架,主要有以下几个亮点:
  >
  > - 事件驱动( event-driven),高性能;
  >   - 基于回调
  >     - 需要编写函数的处理动作, 调用程序猿不需要管(程序猿不知道调用的时机)
  >     - 当某个具体的事件产生之后(事件的产生是随机的), 这个函数才会被调用
  >     - 我可以将这个事件的处理动作注册给操作系统或者是框架
  >       - 委托框架或者操作系统检测这个事件, 事件被检测到之后, 处理函数被调用
  > - 轻量级,专注于网络;
  > - 源代码相当精炼、易读;
  >   - 现阶段不建议看
  >   - 如果看建议看低版本的代码
  > - 跨平台,支持 Windows、 Linux、 BSD(是Unix的衍生系统) 和 Mac OS;
  > - 支持多种 I/O 多路复用技术, epoll、 poll、 select 和 kqueue 等;
  >   - linux/max: epoll、 poll, select
  >   - windows: select
  >   - BSD: kqueue 
  >   - I/O操作是异步的, 并且是非阻塞
  >     - read/recv 接收数据, 不是数据到达之后马上就接收了
  >     - 委托内核检测 -> 内核检测到了之后 -> 通知程序猿写的程序 -> 开始处理
  >       - 在单线程/进程的IO转接服务器端, 文件描述的处理是线性的
  >         - 不是时时的通信
  > - 支持 I/O,定时器和信号等事件;
  >   - IO: 读事件, 写事件
  >   - 定时器: 超时处理, 强制解除阻塞的
  >   - 信号: linux中的信号, window中没有信号
  >   - 异常事件
  > - 支持注册事件优先级。
  >   - 可以通过提供的函数进行优先级设置
  >   - 默认只有一个优先级, 所有事件默认优先级相同

8.libevent的安装和解决动态库找不到的问题

```shell
  # 下载地址: http://libevent.org/
  # 源码的方式进行安装
  - 将压缩包解压: libevent-2.1.8-stable.tar.gz
  $ tar zxvf libevent-2.1.8-stable.tar.gz
  - 进入到解压目录 - libevent-2.1.8-stable 
  $ cd libevent-2.1.8-stable 
  - 找 README / README.md / INSTALL -> 从里边找安装步骤
  - 如果没找到, 安照默认的安装流程安装即可
  # 标准的源码安装:
  1. 从当前源码目录中找一个叫 configure 可执行文件, 执行该文件
      $ ./configure  # 检测当前系统的安装环境, 检测没问题会生成 makefile 文件
  2. 根据makefile中的规则构建项目
      # 构建之后会得到可执行程序/动态库/静态库
      $ make
  3. 安装
      - 头文件: 从安装目录拷贝到系统目录头文件目录
      - 库文件: 动态库/静态库, 从安装目录拷贝到系统的库目录
      - 可执行程序: 从安装目录拷贝到系统的二进制目录中 /bin , /usr/bin
      $ sudo make install       # 实际就是文件拷贝

9.事件处理框架的创建

 3. 安装
      - 头文件: 从安装目录拷贝到系统目录头文件目录
      - 库文件: 动态库/静态库, 从安装目录拷贝到系统的库目录
      - 可执行程序: 从安装目录拷贝到系统的二进制目录中 /bin , /usr/bin
      $ sudo make install       # 实际就是文件拷贝
      
  # 如何验证这个库装好了, 并且可以使用?
  进入到安装目录的 sample 目录中, 可以编译 hello-world.c , 动态库名叫: libevent.so
  $ gcc hello-world.c -o hello -levent
  

10.启动事件循环event_base_dispatch()函数

# 2. 事件处理框架 - event_base

> 使用 libevent函数之前需要分配一个或者多个 event_base 结构体。每个event_base 结构体持有一个事件集合,可以检测以确定哪个事件是激活的。每个 event_base 都有一种用于检测哪种事件已经就绪的 “方法”,或者说后端。 

- API函数

  > 在 event_base 底层封装了IO多路转接模型, 并且可以对事件进行检测和处理的
  
  ```c
  // 头文件
  #include <event2/event.h>
  // 创建一个事件处理框架
  struct event_base * event_base_new(void);
  // 释放一个事件处理框架
  // 参数: event_base_new() 函数的返回值
  void event_base_free(struct event_base * base);
  
  // 查看底层支持的IO转接模型
  const char** event_get_supported_methods(void);
  // 查看当前实际处理框架使用的IO转接模型
  const char *event_base_get_method(const struct event_base *base);
  ```

11.事件的终止函数

```c
  // 测试程序
  int main()
  {
      // 1. 创建事件处理框架
      struct event_base* base = event_base_new();
      
      // 2. 查看支持什么样的IO转接函
      // 二级指针指向: char * xx[];
      const char** methods = event_get_supported_methods();
      printf("支持的IO转接模型: \n");
      for(int i=0; methods[i] != NULL; ++i)
      {
          printf("    %s\n", methods[i]);
      }
  
      printf("当前event_base使用的IO转接模型: %s\n", event_base_get_method(base));
  
  
      // 释放资源
      event_base_free(base);
  
      return 0;
  }
  ```

12.事件的创建和销毁struct event

> event_base不停的检测委托的检测是实际是不是发生了, 如果发生了, event_base会调用对应的回调函数, 这个回调函数的用户委托检测事件的时候给的.

- 启动事件循环

  ```c
  // 头文件
  #include <event2/event.h>
  // 启动事件处理框架中的事件循环
  // 参数: event_base_new() 的返回值
  /*
      事件检测过程中的特点:
          举例: 检测读事件
              - 如果对方没有发送数据过来, 会一直持续检测, 等待事件被触发
              - 检测到有读事件, 默认情况下只会被处理一次, 事件循环就停止了, 只能接收一次数据
              - 如果要持续的接收数据, 需要额外设置, 给创建的事件指定 EV_PERSIST 属性
  */ 
  // 这个函数被调用, 内部会进行事件检测, 代码阻

13.将创建的事件添加到事件处理框架event_add()

 // 这个函数被调用, 内部会进行事件检测, 代码阻塞在这一行
  // 条件满足, 检测的就停止了, 应用程序就结束了
  int event_base_dispatch(struct event_base* base);
  
  // 相似的操作 -qt
  int main()
  {
      QApplication a;
      a.exec();    // 应用程序对象开始内部的事件循环
      return 0;
  }
  ```

  

14.事件和事件处理框架之间的框架

- 终止事件循环

  ```c
  // 头文件
  #include <event2/event.h>
  
  // 表示一个时间段, tv_sec + tv_usec
  struct timeval {
      long    tv_sec;      // 秒              
      long    tv_usec;    // 微秒        
  };
  
  // 假设事件循环正在继续, 并且在处理一个实际有效的事件, 代用这个函数终止事件循环
  // 事件循环不会马上终止, 在tv指定的时长之后, 事件就别终止了
  int event_base_loopexit(struct event_base * base, const struct timeval * tv);
  参数:
      - base: 事件处理框架
      - tv: 在指定的时间段之后, 退出事件循环
  // 马上终止事件循环
  int event_base_loopbreak(struct event_base * base);
  ```

15.通过event事件写管道代码

# 4. 事件

- 事件的创建和释放

  ```c
  // 头文件
  #include <event2/event.h>
  
  #define EV_TIMEOUT     0x01    // 定时器超时
  #define EV_READ     0x02    // 读, 检测读缓冲区是否有数据
  #define EV_WRITE     0x04    // 写, 检测写缓冲区是否可写
  #define EV_SIGNAL     0x08    // 信号
  #define EV_PERSIST     0x10    // 设置事件被重复检测
  #define EV_ET         0x20    // 边沿模式

16.使用EVENT事件读写管道测试

// 事件的处理函数, 被libevent框架调用, 实参的指定不是程序猿做的
  // 程序猿可以直接使用回调函数的参数 ===> 需要知道参数的意义
  typedef void (*event_callback_fn)(evutil_socket_t fd, short what, void *arg);
  参数:
      - fd: 文件描述符, 是event_new() 第二个参数
      - what: 记录了实际文件描述符触发的事件
      - arg: event_new() 的最后一个参数
  // 创建一个需要检测的事件, struct event 就是创建出的事件
  // evutil_socket_t == int
  // event_new()函数的本质就是对一个文件描述符进行封装
  // 事件被创建之后, 不能被事件处理框架直接检测
  struct event* event_new(struct event_base * base,evutil_socket_t fd,
                            short what,event_callback_fn cb,void * arg);

17.event_add第二个参数超时时长的说明

参数:
      - base: 事件处理框架
      - fd: 一个文件描述符, 比如管道的文件描述符, 套接字通信的文件描述符
      - what: 要检测的事件, 检测第二个参数 fd 的事件
          - EV_READ: 读事件
          - EV_WRITE: 写事件
          - EV_SIGNAL: 信号事件(linux)
          - EV_ET: 设置边沿模式
      - cb: 函数指针对应一个回调函数, 当检测的事件被触发, 这个函数就被调用
      - arg: 作为实参传递给回调函数cb
          
  // 释放事件资源
  void event_free(struct event * event);

18.struct event中的超时处理

- 事件的添加和删除

  ```c
  struct timeval {
      long    tv_sec;    // 秒                
      long    tv_usec;   // 微妙
  };
  // 事件被创建之后, 不能被事件处理框架直接检测, 需要做添加处理
  int  event_add(struct event * ev,const  struct timeval * tv);
  参数:
      - ev: 通过 event_new() 创建得到的事件
    - tv: 超时时长, 如果不用指定为NULL
          - 检测了一个事件, 并且在tv指定的时间段中没有被触发, 这个事件对应的回调函数会被强制调用
          - 如果指定为NULL, 事件不触发, 对应的回调函数就不被调用
  // 将检测的事件从事件处理框架上删除        
  int  event_del(struct event * ev);

19.带缓冲的事件bufferevent

20.创建带缓冲的事件bufferevent_socket_new()

```c
/*
事件和事件处理框架的关系: struct event 和  struct event_base

1. 创建事件处理框架
    struct event_base* base = event_base_new();
2. 创建事件
    struct event* ev = event_new();
3. 添加到事件处理框架中
    event_add()
4. 启动事件循环
    event_base_dispatch();
        - 添加的事件默认只能被检测一次
        - 如果要持续检测
            - 事件处理完毕之后, 再次添加 event_add()
            - 在创建事的时候, 指定为持续检测 EV_PERSIST
5. 释放资源
    event_free();
    event_base_free();
*/

http://www.dtcms.com/wzjs/178423.html

相关文章:

  • app软件免费模板下载网站seo推广优化平台
  • 网站调用字体优化关键词的方法正确的是
  • ppt中超链接网站怎么做免费信息发布平台网站
  • 东莞市最新疫情情况百度seo关键词工具
  • wordpress伪静态不收录seo关键词排名优化品牌
  • 增城电子商务网站建设线上培训机构
  • 公司网站框架真正免费的网站建站平台有哪些
  • 建设工程交易服务中心关键词优化seo费用
  • 做网站阜阳免费b站软件推广网站
  • 永久免费的自建网站指数是什么意思
  • 青岛网站建设方案策划广告代理
  • 学生兼职做网站重庆seo关键词排名
  • 模板网站如何引擎收录做推广的都是怎么推
  • 网站建设静态部分报告总结网站开发是做什么的
  • 深圳品牌做网站公司哪家好广州seo网站推广优化
  • 长春网站优化常识报个计算机培训班多少钱
  • asp网站发邮件今日热搜头条
  • 帮人做诈骗网站获利西安百度提升优化
  • 四川住建厅官方网站的网址免费推广的网站平台
  • 网站开发亿码酷技术seo网址超级外链工具
  • 企业解决方案工作组东莞seo推广公司
  • 网店运营与管理搜索引擎推广与优化
  • 网站建设意见建议东莞网络推广托管
  • 微信公众号如何创建seo百度推广
  • 南京市工程建设交易中心网站公司网站设计公司
  • 山西网站制作设计石家庄百度关键词搜索
  • 网站建设规划文档关键词是什么
  • 网站开发教学网百度的广告
  • 网站服务合同用交印花税吗亚马逊免费的关键词工具
  • 游戏网站平台怎么做百度问答