libuv使用笔记

libuv使用笔记

获取libuv

官网http://libuv.org/
下载列表https://dist.libuv.org/dist/
git仓库https://github.com/libuv/libuv

笔者从git仓库直接clone下来的,
最新的TAG是1.44.1,切一下tag

$ git checkout v1.44.1

编译

$ ./autogen.sh 
./autogen.sh: 1: ./autogen.sh: automake: not found
./autogen.sh: 33: test: Illegal number: 
./autogen.sh: 34: test: Illegal number: 
+ libtoolize --copy
./autogen.sh: 43: ./autogen.sh: libtoolize: not found

报错了,蛋蛋,没有工具,先装工具

$ sudo apt-get install autoconf automake libtool

$ ./autogen.sh 
...

生成了configure文件,但是我看到CMakeLists.txt,我什么不直接用CMake编译呢?
在这里插入图片描述

因为没有看完README.md, 直接跟着做了。

个人比较喜欢CMake编译,重新来。

$ mkdir -p build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=./out/
$ make -j4
$ make install
$ cd out
$ tree
.
├── include
│   ├── uv
│   │   ├── aix.h
│   │   ├── bsd.h
│   │   ├── darwin.h
│   │   ├── errno.h
│   │   ├── linux.h
│   │   ├── os390.h
│   │   ├── posix.h
│   │   ├── stdint-msvc2008.h
│   │   ├── sunos.h
│   │   ├── threadpool.h
│   │   ├── tree.h
│   │   ├── unix.h
│   │   ├── version.h
│   │   └── win.h
│   └── uv.h
├── lib
│   ├── cmake
│   │   └── libuv
│   │       ├── libuvConfig.cmake
│   │       └── libuvConfig-noconfig.cmake
│   ├── libuv_a.a
│   ├── libuv.so -> libuv.so.1
│   ├── libuv.so.1 -> libuv.so.1.0.0
│   ├── libuv.so.1.0.0
│   └── pkgconfig
│       ├── libuv.pc
│       └── libuv-static.pc
└── share
    └── doc
        └── libuv
            └── LICENSE

9 directories, 24 files

编译比较顺利

测试

官方给的HelloWorld代码http://docs.libuv.org/en/v1.x/guide/basics.html#hello-world

#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

int main()
{
   uv_loop_t *loop = (uv_loop_t *)malloc(sizeof(uv_loop_t));
   uv_loop_init(loop);

   printf("Now quitting.\n");
   uv_run(loop, UV_RUN_DEFAULT);

   uv_loop_close(loop);
   free(loop);
   return 0;
}

编译一下,找不到库,加一下动态库查找路径,下面是我点电脑上编译的libuv路径,注意修改

export LD_LIBRARY_PATH=/home/liuyuelong/workspace/libuv.git/build/out/lib:$LD_LIBRARY_PATH

不知道代码干了嘛,反正编译运行都OK,说明编译的库没有问题。

用户手册

用户手册http://docs.libuv.org/en/v1.x/guide.html

TCP服务端监听

之前把Helloworld搞定了,接下来搞个TCP服务端玩玩
http://docs.libuv.org/en/v1.x/guide/networking.html#server

这个手册代码感觉都不全,什么鬼。
不管,搞起来再说。

#include <stdio.h>
#include <stdlib.h>
#include <uv.h>

#include "sys/socket.h"

#define DEFAULT_PORT 8060
#define DEFAULT_BACKLOG SOMAXCONN

void on_new_connection(uv_stream_t *server, int status)
{
   printf("on_new_connection:%s\n", status);
}

int main()
{
   sockaddr_in addr;
   auto loop = uv_default_loop();

   uv_tcp_t server;
   uv_tcp_init(loop, &server);

   uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr);

   uv_tcp_bind(&server, (const struct sockaddr *)&addr, 0);
   int r = uv_listen((uv_stream_t *)&server, DEFAULT_BACKLOG, on_new_connection);
   if (r)
   {
      fprintf(stderr, "Listen error %s\n", uv_strerror(r));
      return 1;
   }
   return uv_run(loop, UV_RUN_DEFAULT);
}

backlog这个值找了半天,都忘记了,我直接使用了#include "sys/socket.h"中定义的SOMAXCONN;
在这里插入图片描述

在on_new_connection中做了断点,用浏览器敲地址,触发一下,回调中断点被触发了,挺好,索命TCP进来了。

接受客户端

改造回调函数

void on_new_connection(uv_stream_t *server, int status)
{
   printf("on_new_connection:%s\n", status);
}

TCP服务端通讯

监听搞定了,怎么通讯呢?

在这里插入图片描述

### 使用 libuv 进行 TCP 开发 #### 创建事件循环 为了使用 `libuv` 的功能,首先需要创建一个事件循环实例。这可以通过调用 `uv_loop_t *loop = uv_default_loop();` 来完成。 ```c #include <uv.h> int main() { uv_loop_t *loop = uv_default_loop(); } ``` #### 初始化TCP句柄 初始化一个新的 TCP 句柄用于监听传入连接或建立新的客户端连接: ```c uv_tcp_t server; uv_tcp_init(loop, &server); ``` #### 绑定地址并监听端口 设置服务器套接字选项,并绑定到指定 IP 地址和端口号上准备接收新连接请求[^1]。 ```c struct sockaddr_in addr; uv_ip4_addr("0.0.0.0", 7000, &addr); uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0); int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection); if (r) { fprintf(stderr, "Listen error %s\n", uv_strerror(r)); return 1; } ``` #### 处理新连接 当有新的客户端尝试连接时会触发回调函数,在此定义处理逻辑来接受这些连接。 ```c void on_new_connection(uv_stream_t* server, int status) { if (status < 0) { fprintf(stderr, "New connection error %s\n", uv_strerror(status)); // Handle errors here. return; } uv_tcp_t* client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); uv_tcp_init(loop, client); if (uv_accept(server, (uv_stream_t*)client) == 0) uv_read_start((uv_stream_t*)client, alloc_buffer, echo_read); else free(client); } ``` #### 数据读取与写入操作 实现数据传输过程中的读缓冲区分配以及实际的数据读取消息回显给发送方的功能。 ```c void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { buf->base = (char*)malloc(suggested_size); buf->len = suggested_size; } void echo_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { if (nread < 0) { if (nread != UV_EOF) fprintf(stderr, "Read error %s\n", uv_err_name(nread)); uv_close((uv_handle_t*)tcp, NULL); free(buf->base); return; } printf("Received data: %.*s\n", (int)nread, buf->base); uv_write_t* req = new uv_write_t; uv_buf_t wrbuf = uv_buf_init(buf->base, nread); uv_write(req, tcp, &wrbuf, 1, after_write); } void after_write(uv_write_t* req, int status) { delete req; } ``` 通过上述代码片段展示了基于 `libuv` 库构建简单 TCP 服务端应用程序的方法,包括启动事件循环、配置网络接口参数、响应客户接入请求及双向通信等功能模块的设计思路[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值