libuv之基础

2023-10-26

TCP客户端连接步骤:

①  .连接方法

Uv_loop_t *loop = uv_default_loop();

 

uv_tcp_t *client = malloc…;

uv_connect_t* connect_req = malloc…;

 

uv_tcp_init(loop, client)

 

uv_tcp_connect(connect_req,  client, addr,  connect_cb);

 

uv_run(loop);

 

getchar(); //服务端不需要这个,现在还不明白为什么

 

②.回调函数

static void connect_cb(uv_connect_t*req, int status)

{

         int r;

         uv_buf_t buf = uv_buf_init("just test", 10);

 

这必须是动态分配内存,在uv_write函数内部会对这个指针赋值。

         uv_write_t *reqw = (uv_write_t*)malloc(sizeof *reqw);

 

         在write_cb中,释放分配的内存。

         r = uv_write(reqw, (uv_stream_t*)(req->handle),&buf, 1, write_cb);

}

 

static void write_cb(uv_write_t*req, int status)

{

}

static void read_cb(uv_stream_t*tcp, ssize_t nread, uv_buf_t buf)

{

}

uv_connect_tis a subclass of uv_req_t

 

 

 

 

 

 

 

 

 

2.TCP服务端连接步骤

①.连接方法

         loop = uv_default_loop();

 

         structsockaddr_in addr = uv_ip4_addr("127.0.0.1",5432);

         int r;

 

         server = (uv_handle_t*)&tcpServer;

         r = uv_tcp_init(loop, &tcpServer);

         if (r){

                   std::cout << "Socket creation error" <<std::endl;

                   return;

         }

 

         r = uv_tcp_bind(&tcpServer, addr);

         if (r){

                   std::cout << "Bind error" << std::endl;

                   return;

         }

 

         r =uv_listen((uv_stream_t*)&tcpServer, 10, on_connection);

         if (r){

                   std::cout << "Listen error" << std::endl;

                   return;

         }

 

         uv_run(loop);

 

②.回调函数

static voidon_connection(uv_stream_t* server, int status)

{

         uv_stream_t* stream;

         int r;

用这种方式来初始化一个新连接

         stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t));

         ASSERT(stream != NULL);

         r = uv_tcp_init(loop,(uv_tcp_t*)stream);

         stream->data = server;

         r = uv_accept(server, stream);

}

 

*uv_stream_t is a subclass of uv_handle_t

 *

 * uv_stream is an abstract class.

 *

 * uv_stream_t is the parent class of uv_tcp_t,uv_pipe_t, uv_tty_t, and

 * soon uv_file_t.

 

在客户端的连接中

Uv_tcp_connect(connect_req…);connect_req是一个uv_connect_t*参数,相应的connect_cb的第一个参数为uv_connect_t*,(uv_connect_t是uv_req_t的子类)

 

服务端的连接中

uv_listen((uv_stream_t*)&tcpServer,10, on_connection);相应的on_connect的第一个参数为uv_stream_t*

 

看来node.js的思想和ACE非常像,把请求对象和连接对象分别封装成不同概念的东西。

 

3.tcp –open

创建套接字然后使用uv_tcp_open,再uv_tcp_connect时,函数内部不会再创建套接字,仅此而已。

 

4.tcp_read_stop

Uv_read_stop((uv_stream_t*)&tcp_handle);

Uv_close((uv_handle_t*)tcp_handle);

 

UDP客户端:

         uv_udp_send_t req;

         r = uv_udp_init(uv_default_loop(),&client);

         ASSERT(r == 0);

 

         buf = uv_buf_init("PING", 4);

         r = uv_udp_send(&req, &client,&buf, 1, addr, cl_send_cb);

 

         voidcl_send_cb(uv_udp_send_t* req, intstatus)

         {}

UDP服务端:

         r = uv_udp_init(uv_default_loop(),&server);

         ASSERT(r == 0);

 

         r = uv_udp_bind(&server, addr, 0);

         ASSERT(r == 0);

 

         r = uv_udp_recv_start(&server,alloc_cb, sv_recv_cb);

         ASSERT(r == 0);

 

 

 

 

 

 

static void sv_recv_cb(uv_udp_t* handle,

                                                        ssize_tnread,

                                                        uv_buf_tbuf,

                                                        struct sockaddr* addr,

                                                        unsigned flags)

{}

 

定时器

int64_t   start_time = uv_now(uv_default_loop());

 

void never_cb(uv_timer_t* handle, int status)

{

         std::cout << "never_cb should never be called"<< std::endl;

}

 

static voidonce_close_cb(uv_handle_t*handle)

{}

static voidonce_cb(uv_timer_t* handle, int status)

{

 

         uv_close((uv_handle_t*)handle, once_close_cb);

 

         uv_update_time(uv_default_loop());

}

 

         r = uv_timer_init(uv_default_loop(), &never);

         ASSERT(r == 0);

         r = uv_timer_start(&never, never_cb, 100, 100);

         ASSERT(r == 0);

         r = uv_timer_stop(&never);

         ASSERT(r == 0);

         uv_unref((uv_handle_t*)&never);

 

         uv_run(uv_default_loop());

 

 

 

 

同步对象

uv_cond_init(&signal_cond)

uv_cond_destroy(&signal_cond);

 

 

If libuv has been compiled with debuggingenabled, uv_mutex_destroy()uv_mutex_lock() and uv_mutex_unlock() will abort() on error.Similarly uv_mutex_trylock() will abort if the error is anything otherthan EAGAIN.

 

Note:

Libuv 里面有read/writeuv_rwlock_t numlock;

Warning

mutexesand rwlocks DO NOT work inside a signal handler, whereas uv_async_send does.

 

线程间通信用uv_async_t

 

线程对象

uv_thread_t tid;

         int r;

 

         r = uv_thread_create(&tid,thread_entry, (void*)42);

         ASSERT(r == 0);

 

         r = uv_thread_join(&tid);

 

线程池

r = uv_queue_work(uv_default_loop(),&work_req, NULL, after_work_cb); //倒数第二个参数为NULL,返回-1,after_work_cb也不会被调用

  ASSERT(r == -1);

 

libuv work queue

uv_queue_work() is a convenience function that allows an application torun a task in a separate thread, and have a callback that is triggered when thetask is done. A seemingly simple function, what makes uv_queue_work() tempting is that it allows potentiallyany third-party libraries to be used with the event-loop paradigm. When you useevent loops, it is imperativeto make sure that no function which runs periodically in the loop thread blockswhen performing I/O or is a serious CPU hog, because this means the loop slows downand events are not being dealt with at full capacity.

意思是:IO线程里面不应该有阻塞操作,libuv的处理方式是让系统自己处理这些阻塞操作。就是IOCP嘛。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

libuv之基础 的相关文章

  • c++网络编程3:UDP编程

    一 概念 UDP是传输层中面向无连接的协议 所以UDP丢包后是不会重传的 而且他在编程上服务端和客户端是没有区别的 有的只是 虚拟上 的服务端和客户端 他在编程的实现上也很简单 不像TCP那么复杂 二 UDP终端的编程 由于UDP在服务端和
  • 不同型号服务器esxi,如果管理多个esxi服务器

    如果管理多个esxi服务器 没有 装一个vcenter吧 可以集中管理 多台服务器之间还可以做双机热备等功能 很好用 至于注册序列号 你漫天都是 你可以把分数拉高一点 我送给你一个 哈哈 如何给esxi搭建ntp服务器 提在ESX ESXi
  • Windows系统的JDK安装与配置

    1 选择JDK版本 以在Windows 64位平台上安装JDK 8版本为例 JDK 8 Windows版官网下载地址 https www oracle com java technologies downloads java8 window
  • Redis的安装

    环境 用的Linux系统阿里云服务器 1 在redis官网下载最新稳定版的安装包 官网网址 https redis io 2 下载完的安装包通过Xftp上传到 opt目录下 3 连接上远程服务器60 205 189 176端口22 输入下面
  • 离线实时一体化数仓与湖仓一体—云原生大数据平台的持续演进

    林伟 阿里云智能研究员 阿里云智能通用计算平台MaxCompute 机器学习PAI平台技术负责人 本篇内容将从三个部分为读者讲述离线实时一体化数仓与湖仓一体 云原生大数据平台的持续演进 通过从数据湖到数仓的历史 反思为什么要做湖仓一体 以及
  • 向“全栈”进发,大型线上商城实战项目,Spring Boot + Vue 前后端分离版本的商城来了(文末有视频)

    新蜂商城 Vue 版本 它来了 文末有视频 如上图所示 新蜂商城 Vue 版本已经开发完成 这是新蜂商城开源项目的第一个大版本更新 根据大量的用户调研 最终决定将新蜂商城升级为 Spring Boot Vue 两个流行技术栈的前后端分离商城
  • Web开发-基础环境配置

    Web开发 基础环境配置 回炉再造 2021 Vue3 0 前端全家桶学习笔记 web前端职业发展路线 技术范围广 发展速度快 兼容浏览器众多 核心技术 html css JavaScript BOM DOM 新的技术 html5 css3
  • QT5使用PCAN读取CAN数据

    文章目录 QT5使用PCAN读取CAN数据 CAN Bus example 重点讲解 pro文件 创建CAN bus Device 参数设置 接收报文 PCAN支持的QCanBusDevice ConfigurationKey类型 QT5使
  • IDEA 插件代理设置

    一 ctrl alt s 打开设置
  • pytorch JIT浅解析

    概要 Torch Script中的核心数据结构是ScriptModule 它是Torch的nn Module的类似物 代表整个模型作为子模块树 与普通模块一样 ScriptModule中的每个单独模块都可以包含子模块 参数和方法 在nn M
  • Python告诉你:李子柒的螺蛳粉到底有多火?

    居家隔离的日子里 各类方便速食食品成了许多人的心头爱 特别是螺蛳粉 异军突起 火遍全网 几乎卖到脱销 有的螺蛳粉热销店铺的购买页面还显示 现在下单 预售40天后发货 这是种什么操作 万万没想到 这些日子发不出货的 除了口罩 还有螺蛳粉 今天

随机推荐

  • 单调队列优化的DP问题

    概述 单调队列就是通过排除求最值时候的冗余 从而是队列具有性质 可以方便求解问题 DP的两个阶段 朴素DP的基本原理 闫氏DP分析法 对朴素DP进行优化 闫氏DP分析法的拓展 在一个有限的集合中求最值 单调队列练习 135 最大子序和 输入
  • JAVA抠图证件照,大头照更换背景或透明

    本文是基础版 使用算法实现请查看 http t csdn cn U8Y4C 使用hutool包 maven引入
  • 道德经学习202220820

    第一章 道可道 非常道 名可名 非常名 无 名天地之始 有 名万物之母 故常无 欲以观其妙 常有 欲以观其徼 jiao 此两者 同出而异名 同谓之玄 玄之又玄 众妙之门 能用言语说出来的道 都不是永恒的终极的道 能形容出来的名都不是永恒的终
  • 22年新款MacBookAir屏幕解析

    先说结论 搭载M2芯片的AIR 很值得买 屏幕 Liquid视网膜显示屏 像素 2550 1664 亮度 500nit 色域 P3 技术 原彩显示技术 Liquid是液晶的意思 但在这里 Liquid是圆角的意思 可以这么说 搭载M2芯片的
  • 【设计模式】-监听者模式和观察者模式的区别与联系

    前言 监听者模式和观察者模式在平时开发中或在Spring源码中经常有碰到 两者乍看上去好像差不多 但为何会分为两种不同的设计模式 究竟是人性的扭曲还是道德的沦丧 让我们一起走进本篇 深入解析两者的异同和使用场景 目录 1 介绍 1 1监听者
  • 数据隐私、AI 交互和知识管理:DB-GPT 的综合解决方案

    python telegram bot python telegram bot Stars 22 9k License GPL 3 0 这个项目是一个提供纯 Python 异步接口的 Telegram Bot API 库 它与 Python
  • extern声明外部结构体

    结构体是一种类型 定义一种类型最好是在 h文件定义 这样其他地方想用这个结构体 只需包含此 h文件即可 但是定义结构体变量的话 最好载 c文件定义 为了防止重复定义 所以不建议在 h文件中定义变量 然后 h里面extern声明 其他 c文件
  • 1 恢复MySQL误删数据

    作者 一个人的孤独自白 cnblogs com mrl p 9959365 html 相信后端研发的同学在开发过程经常会遇到产品临时修改线上数据的需求 如果手法很稳那么很庆幸可以很快完成任务 很不幸某一天突然手一抖把表里的数据修改错误或者误
  • 利用OpenLayers创建wkt字符串

    var polygon OpenLayers Geometry Polygon createRegularPolygon new OpenLayers Geometry Point 6 49 2 18 0 var feature new O
  • blob (Binary Large Object)

    在深度学习中 二进制大对象 Binary Large Object BLOB 通常指的是存储模型权重或预训练模型的文件 这些文件可以非常大 通常以二进制格式存储 并在深度学习框架中用于加载和保存模型 在深度学习中 模型的权重是模型在训练过程
  • recyclerView的滑动

    1 无感知滑动 layoutManager scrollToPositionWithOffset int position int offset 第一个参数是指第几项 第二个参数是跟顶部的距离 当你的屏幕只能显示10项就满了 但是你的dat
  • 数组以及指针数组遍历&Demo

    遍历数组以及指针数组 Demo By C include
  • 【以太坊开发】 问题 etherbase must be explicitly specified

    1 使用geth启动在私有链环境下 提示如下问题 html view plain copy Updated mining threads threads 0 INFO 08 17 21 31 30 Transaction pool pric
  • flutter pubspec添加依赖无法获取flutter_test

    pubspec yaml 文件初次添加的时候拷过来没格式化 packages get 一直失败各种尝试无果 后来格式化了一下 就可以了
  • 【rust】

    系列文章目录 rust 00 开发环境搭建 rust 01 编译并运行第一个rust程序 rust 02 语法基础 变量 不可变 和常量 rust 03 语法基础 数据类型 rust 04 语法基础 函数 rust 05 语法基础 流程控制
  • windows下启动nacos(单机配置)

    windows下启动nacos 下载nacos 找到github地址 并根据对应的版本进行下载 如果下载过慢的话 可以使用迅雷下载 1下载完成后 进行解压 之后打开 conf application properties文件 2 打开后 我
  • 机器学习实战——朴素贝叶斯

    目录 一 朴素贝叶斯理论 1 概述 2 朴素贝叶斯特点 3 贝叶斯决策理论 4 条件概率与全概率公式 5 贝叶斯推断 二 朴素贝叶斯分类器应用 拉普拉斯修正 三 垃圾邮件分类 一 朴素贝叶斯理论 1 概述 朴素贝叶斯算法是有监督的学习算法
  • vue3.0模板

    GitHub Mstian Vue Onepiece Admin vue3 elementPlus后台管理简单模板https github com Mstian Vue Onepiece Admin
  • null,default关键字

    一 null关键字 1 null是空的意思 在表中 默认情况下 所有的字段值都可以为空 1 建表期间 可以对某一字段进行非空约束 not null 在insert时 此字段必须要有数据 create table temo id number
  • libuv之基础

    TCP客户端连接步骤 连接方法 Uv loop t loop uv default loop uv tcp t client malloc uv connect t connect req malloc uv tcp init loop c