c++ 使用libuv库

一、克隆libuv源码

  • 打开命令行或终端。
  • 使用git clone命令克隆libuv的源码仓库。例如:
    git clone https://github.com/libuv/libuv.git
  • 这将在当前目录下创建一个名为libuv的目录,其中包含libuv的源码。

二、编译安装libuv

  • 进入libuv的源码目录:
cd libuv
  • 运行sh autogen.sh以生成配置脚本(如果存在autogen.sh)。这可能在某些libuv版本中需要,但不一定。
  • 运行./configure脚本以准备编译环境。这个脚本会检查您的系统环境,并生成适合您的系统的Makefile文件。
  • 编译libuv:
    make
  • (可选)运行测试以确保编译没有问题:
    make check
  • 安装libuv:
    sudo make install
  • 这会将libuv库安装到您的系统中,通常是/usr/local/lib目录。

三、把libuv文件、动态库放到项目中

     将libuv下的include文件、.libs/libuv.so放到你项目中去

    例如: 我把include文件放到我的项目中的Include/Libuv/UVInclude中

                把libuv.so放到Lib中

── build
├── CMakeLists.txt
├── Include
│   └── Libuv
│       ├── Libuv.cpp
│       ├── Libuv.h
│       └── UVInclude
│           ├── uv
│           │   ├── aix.h
│           │   ├── bsd.h
│           │   ├── darwin.h
│           │   ├── errno.h
│           │   ├── linux.h
│           │   ├── os390.h
│           │   ├── posix.h
│           │   ├── sunos.h
│           │   ├── threadpool.h
│           │   ├── tree.h
│           │   ├── unix.h
│           │   ├── version.h
│           │   └── win.h
│           └── uv.h
├── Lib
│   └── libuv.so
└── Main.cpp

四、CMakeLists.txt编译规则增加

#限定cmake 版本最低2.8
cmake_minimum_required(VERSION 2.8)#项目名称
project(main)#向编译单元添加包含目录的路径。这允许源文件包含来自指定目录的头文件
include_directories(Include)#用于将指定目录下的所有源文件列表赋值给一个变量
aux_source_directory(Include/Libuv SRC_LIST1)#从指定目录查找对应的库
find_library(LIB libuv.so ./Lib)if(LIB)message("find libuv.so")
else()message("not find libuv.so")
endif()#添加一个可执行目标以及它的源文件
add_executable(main Main.cpp ${SRC_LIST1})#为指定的目标添加链接库, 这里增加libuv.so库
target_link_libraries(main ${LIB})

五、项目使用libuv库实现tcp连接

1、建立类( Libuv.h、Libuv.cpp) 封装使用

   Libuv.h代码

#ifndef LIBUV
#define LIBUV
#include "UVInclude/uv.h"class Libuv{public:Libuv();void Init();private:};#endif

Libuv.cpp代码

#include<iostream>
#include <cstdlib>
#include <sstream>
#include "Libuv.h"
using namespace std;Libuv::Libuv(){}string get_client_ip(uv_tcp_t* client){
// 获取客户端的 socket 信息  struct sockaddr_storage peer_addr;  int peer_addr_len = sizeof(peer_addr);  if (uv_tcp_getpeername(client, (struct sockaddr*)&peer_addr, &peer_addr_len) == 0) {  char ip_str[INET6_ADDRSTRLEN];  void* addr;int port;if (peer_addr.ss_family == AF_INET) {  struct sockaddr_in* in = (struct sockaddr_in*)&peer_addr;  addr = &(in->sin_addr);port= ntohs(in->sin_port);} else {  struct sockaddr_in6* in6 = (struct sockaddr_in6*)&peer_addr;  addr = &(in6->sin6_addr); port=ntohs(in6->sin6_port);}  inet_ntop(peer_addr.ss_family, addr, ip_str, sizeof(ip_str));  //printf("Accepted connection from client IP: %s\n", ip_str); std::ostringstream oss;oss<<ip_str<<":"<<port;return oss.str();} else {  // 如果获取客户端信息失败,可以获取错误信息  //fprintf(stderr, "Getpeername error %s\n", uv_strerror(uv_last_error(uv_default_loop())));  cout<<"getpeername error"<<endl;}return "";
}
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {  *buf = uv_buf_init((char*)malloc(suggested_size), suggested_size);  
}  void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {  string ip_str = get_client_ip((uv_tcp_t*)stream);if (nread > 0) {  std::cout <<"client:"<< ip_str<< ",Received: " << buf->base << std::endl;  } else if (nread < 0) {  if (nread != UV_EOF)  //std::cerr << "Read error " << uv_err_name(uv_last_error(uv_default_loop())) << std::endl;  uv_close((uv_handle_t*) stream, NULL);cout<<"close by client,ip:"<<ip_str<<endl;} else {  /* EOF: call uv_close() */  cout<<"close by eof"<<endl;uv_close((uv_handle_t*) stream, NULL);  }  free(buf->base);  
} 
void on_connect_cb(uv_stream_t* server, int status) {  if (status == -1) {  //std::cerr << "Connection error: " << uv_strerror(uv_last_error(uv_default_loop())) << std::endl;  cout<<"connection error"<<endl;return;}uv_tcp_t* client =(uv_tcp_t*)malloc(sizeof(uv_tcp_t));uv_tcp_init(uv_default_loop(),client);if(uv_accept(server, (uv_stream_t*)client) == 0) {string ip_str = get_client_ip(client);cout<<"accepted new connection, ip:"<<ip_str<<endl;uv_read_start((uv_stream_t*)client, alloc_buffer, read_cb);}else{cout<<"accepted error"<<endl;free(client);}
}void Libuv::Init(){cout<<"Libuv Init"<<endl;uv_loop_t *loop = uv_default_loop();uv_tcp_t server;uv_tcp_init(loop, &server);struct sockaddr_in addr;uv_ip4_addr("0.0.0.0", 9999, &addr);uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);uv_listen((uv_stream_t*)&server, 128, on_connect_cb);uv_run(loop, UV_RUN_DEFAULT);
}

2、main 使用Libuv类

main.cpp 代码

#include<iostream>
#include "Libuv/Libuv.h"using namespace std;int main(){Libuv libuv;libuv.Init();return 0;
}

六、运行结果

 服务器:

Libuv Init
accepted new connection, ip:127.0.0.1:49094
client:127.0.0.1:49094,Received: hello worldclose by client,ip:127.0.0.1:49094

客户端:

Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
hello world
^]telnet> q
Connection closed.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/6642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握算法艺术

学习算法是计算机科学领域的一个重要分支&#xff0c;它对提高编程能力、解决复杂问题以及参与竞争激烈的技术面试都非常关键。 概要&#xff1a; 1. 引言&#xff1a;为什么学习算法很重要&#xff1f; - 解释算法在计算机科学中的作用 - 讨论算法知识对于技术面试和职…

多级留言/评论的功能实现——SpringBoot3后端篇

目录 功能描述数据库表设计后端接口设计实体类entity 完整实体类dto 封装请求数据dto 封装分页请求数据vo 请求返回数据 Controller控制层Service层接口实现类 Mapper层Mybatis 操作数据库 补充&#xff1a;返回的数据结构自动创建实体类 最近毕设做完了&#xff0c;开始来梳理…

github.com/gin-contrib/timeout应前置使用

首先&#xff0c;gin的中间件是有执行顺序的&#xff0c;就是按照添加的顺序进行的。之前没在意&#xff0c;我把timeout中间件放在了最后面&#xff0c;导致业务一直不正常&#xff0c;后面debug源码总算看明白了&#xff1a; 源码入口&#xff1a; func(c *gin.Context) {fi…

WPF应用程序XAML

当WPF应用程序创建好后&#xff0c;系统会自动添加一个Grid控件到窗体上&#xff0c;通过Grid控件能够方便地对界面进行布局.下面代码中为Grid控件添加了两行两列&#xff0c;分别用RowDefinitions属性ColumnDefinitions属性表示行的集合和列的集合&#xff0c;集合中有RowDefi…

Python爬虫--伪装成浏览器

把爬虫伪装成浏览器 1. 技术原理 我们不讲很官方的属于&#xff0c; 简单的讲就是&#xff0c;一些论坛啊&#xff0c;博客啊 为防止别人爬他们的文章&#xff0c; 通常会判断是不是浏览器访问&#xff0c;如果不是那就屏蔽。 2. 实战 由于 urlopen() 对于一些HTTP的高级功…

【区块链】共识算法简介

共识算法简介 区块链三要素&#xff1a; 去中心化共识算法智能合约 共识算法作为区块链三大核心技术之一&#xff0c;其重要性不言而喻。今天就来简单介绍共识算法的基本知识。 最简单的解释&#xff0c;共识算法就是要让所有节点达成共识&#xff0c;保证少数服从多数&#x…

噪声嵌入提升语言模型微调性能

在自然语言处理&#xff08;NLP&#xff09;的快速发展中&#xff0c;大模型&#xff08;LLMs&#xff09;的微调技术一直是研究的热点。最近&#xff0c;一篇名为《NEFTUNE: NOISY EMBEDDINGS IMPROVE INSTRUCTION FINETUNING》的论文提出了一种新颖的方法&#xff0c;通过在训…

【数据结构】--- 深入剖析二叉树(上篇)--- 初识树和二叉树

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 数据结构之旅 &#x1f3e0; 初识树 &#x1f4d2; 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点…

分布式与一致性协议之一致哈希算法(三)

一致哈希算法 如何使用一致哈希算法实现哈希寻址 我们一起来看一个例子&#xff0c;对于1000万个key的3节点KV存储&#xff0c;如果我们使用一致哈希算法增加1个节点&#xff0c;即3节点集群变为4节点集群&#xff0c;则只需要迁移24.3%的数据,如代码所示 package mainimpor…

微搭低代码入门03页面管理

目录 1 创建页面2 页面布局3 页面跳转总结 上一篇我们介绍了应用的基本操作&#xff0c;掌握了应用的概念后接着我们需要掌握页面的常见操作。 1 创建页面 打开应用的编辑器&#xff0c;在顶部导航条点击创建页面图标 在创建页面的时候可以从空白新建&#xff0c;也可以使用模…

【原件】软件需求分析报告

第1章 序言 第2章 引言 2.1 项目概述 2.2 编写目的 2.3 文档约定 2.4 预期读者及阅读建议 第3章 技术要求 3.1 软件开发要求 第4章 项目建设内容 第5章 系统安全需求 5.1 物理设计安全 5.2 系统安全设计 5.3 网络安全设计 5.4 应用安全设计 5.5 对用户安全管理 …

Mysql复习笔记: 基础概念(待补充)

一. 基础概念 通用概念: 网络连接必须得分配给一个线程去进行处理&#xff0c;由一个线程来监听请求以及读取请求数据&#xff0c;比如从网络连接中读取和解析出来一条我们的系统发送过去的SQL语句 在数据库中&#xff0c;哪怕执行一条SQL语句&#xff0c;其实也可以是一个独立…

PostgreSQL自带的命令行工具06- pg_isready

PostgreSQL自带的命令行工具06- pg_isready 基础信息 OS版本&#xff1a;Red Hat Enterprise Linux Server release 7.9 (Maipo) DB版本&#xff1a;16.2 pg软件目录&#xff1a;/home/pg16/soft pg数据目录&#xff1a;/home/pg16/data 端口&#xff1a;5777pg_isready 是 Po…

2024牛客五一集训派对day2 Groundhog Looking Dowdy 个人解题思路

前言&#xff1a; 被实验室教练要求要打的这次五一牛客的训练赛&#xff0c;这些区域赛难度的题对于大一的我来说难度实在是太高了&#xff0c;我和我的队友只写了一些非常简单的签到题&#xff0c;其他题目都没怎么看&#xff08;我们太弱了&#xff09;&#xff0c;但我可以分…

线上线下交友社区系统,支持打包小程序/公众号/H5,源码交付!

上网交友的好处有很多&#xff0c;以下是一些主要的好处&#xff1a; 1. 拓展人际关系&#xff1a;通过上网交友可以认识更多的人&#xff0c;拓展自己的社交圈。这有助于扩大自己的视野、增加人生经验和开阔心胸。 2. 找到志同道合的朋友&#xff1a;在网络上&#xff0c;我们…

JavaWeb请求响应概述

目录 一、请求响应流程-简述 二、深入探究 三、DispatcherServlet 四、请求响应流程-详细分析 一、请求响应流程-简述 web应用部署在tomcat服务器中&#xff0c;前端与后端通过http协议进行数据的请求和响应。前端通过http协议向后端发送数据请求&#xff0c;就可以访问到部…

持续总结中!2024年面试必问 100 道 Java基础面试题(二十九)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 100 道 Java基础面试题&#xff08;二十八&#xff09;-CSDN博客 五十七、静态内部类和普通内部类有什么区别&#xff1f; 在Java中&#xff0c;内部类是指定义在另一个类中的类&#xff0c;而内部类的类型有很多…

分割回文串(力扣131)

解题思路&#xff1a;仍就是上递归三部曲&#xff0c;但于此同时要明白此时的index就可以作为切割回文串的线了 具体代码如下&#xff1a; class Solution { private: vector<vector<string>> result; vector<string> path; // 放已经回文的子串 void back…

批量抓取某电影网站的下载链接

思路&#xff1a; 进入电影天堂首页&#xff0c;提取到主页面中的每一个电影的背后的那个urL地址 a. 拿到“2024必看热片”那一块的HTML代码 b. 从刚才拿到的HTML代码中提取到href的值访问子页面&#xff0c;提取到电影的名称以及下载地址 a. 拿到子页面的页面源代码 b. 数据提…

【leetcode】DFS递归题目总结

DFS&#xff08;深度优先搜索&#xff09; 深度优先搜索是一种用于遍历或搜索树或图的算法&#xff0c;其基本思路是从起始节点开始&#xff0c;沿着一条路径一直走到底&#xff0c;直到无法再走下去为止&#xff0c;然后回溯到上一个节点&#xff0c;继续走到另外一个路径&…