好好活就是有意义的事,有意义的事就是好好活
libuv : User guide » Networking
libuv : User guide » Networking

libuv : User guide » Networking

Networking

libuv 中的网络与直接使用 BSD 套接字接口没有太大区别,都是非阻塞的,但概念保持不变。 此外,libuv 提供实用功能来抽象烦人的、重复的和低级任务,例如使用 BSD 套接字结构体来设置sockets、DNS 查找和调整各种套接字参数等。

uv_tcp_t uv_udp_t 结构用于网络 I/O。

注意:本章中的代码示例用于展示某些 libuv API。 它们不是优质代码的示例。 它们会泄漏内存且并不总是正确关闭连接。

TCP

TCP 是一种面向连接的流协议,因此基于 libuv streams基础设施。

server

服务器套接字通过以下方式进行:

  • uv_tcp_init 初始化TCP 句柄
  • uv_tcp_bind 绑定
  • 在句柄上调用uv_listen, 并在客户端请求建立连接时调用回调函数.
  • 使用uv_accept接收连接(在回调函数中执行)
  • 使用stream operations与客户端进行交互

tcp-echo-server/main.c – The listen socket

        uv_close((uv_handle_t*) client, on_close);
    }
}

int main() {
    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);
}

uv_ip4_addr将我们熟悉的Ipv4的地址和端口号,转化为BSD套接字复杂的sockaddr_in结构. 当然, 也可以使用uv_ip4_name得到进行相反的操作.

注意:uv_ip6_* 的操作与ipv4对应的API是类似的.

上述代码大都是同步的, 因为都是CPU任务, 只有uv_listen采用了回调的方式, 其第二个参数是其实就是listen的backlog参数, 详情可以看listen(2).

其实, listen本身并不是一个阻塞的函数, listen是可以直接返回的, 真正的阻塞函数其实是accept, 也就是说, 如果当前没有连接要建立, 那么listen是不会阻塞, 而accept会阻塞!

listen的回调函数中, 我们需要调用accept, 创建连接(即为client创建socket), 并监听这个连接(监听这个socket), 当连接有数据到达时, 触发回调函数, 来读取数据, 这个过程其实就是标准的使用epoll进行网络IO的处理, 和我在Pistache源码中HTTP请求的处理过程是完全一致的.

tcp-echo-server/main.c – Accepting the client

    free(buf->base);
}

void on_new_connection(uv_stream_t *server, int status) {
    if (status < 0) {
        fprintf(stderr, "New connection error %s\n", uv_strerror(status));
        // error!
        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);
    }

其余的函数集与流示例非常相似,可以在代码中找到。 只要记住在不需要套接字时调用 uv_close 即可。 如果您对接受连接不感兴趣,这甚至可以在 uv_listen 回调中完成。

…..(未完)

2条评论

  1. Pingback:libuv : User guide » Processes – Kingdo Station

  2. Pingback:libuv : User guide » Utilities – Kingdo Station

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注