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 world

close 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.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值