一点一滴成长

导航

libuv网络操作

1、获取本机网络地址

  使用uv_interface_addresses()可以获取本机网络地址接口信息,如下所示,其第一个参数是一个指针的指针,因为仅传递指针的话函数内只能改变指针指向的内容,不能改变该指针值,有了指针的地址就可以改变指针的值:

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

int main() {
    char buf[512] = {0};
    uv_interface_address_t* info;
    int count, i;

    //int uv_interface_addresses(uv_interface_address_t** addresses, int* count);
    uv_interface_addresses(&info, &count); //获得所有网口信息
    i = count;

    printf("Number of interfaces: %d\n", count);
    while (i--) {
        uv_interface_address_t addrInterface = info[i]; 

        printf("Name: %s\n", addrInterface.name);
        printf("Internal? %s\n", addrInterface.is_internal ? "Yes" : "No"); //是否是内部IP

        if (addrInterface.address.address4.sin_family == AF_INET) { //IPV4
            uv_ip4_name(&addrInterface.address.address4, buf, sizeof(buf));
            printf("IPv4 address: %s\n", buf);
        }
        else if (addrInterface.address.address4.sin_family == AF_INET6) { //IPV6
            uv_ip6_name(&addrInterface.address.address6, buf, sizeof(buf));
            printf("IPv6 address: %s\n", buf);
        }

        printf("\n");
    }

    uv_free_interface_addresses(info, count);
    return 0;
}

2、TCP服务

  如下实现了一个TCP Server:

#include "uv.h"
#include <assert.h>

uv_loop_t* loop;

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 on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
    if (nread > 0) { //读取到数据
        fprintf(stdout, "reveive data: %s\n", buf->base);
    }
    else if (nread < 0) { //套接字关闭或发生错误
        fprintf(stderr, "Read error: %s\n", uv_strerror(nread));
        
        if (nread == UV_EOF) { /*套接字被关闭(end of file)*/
            
        }
        else  if (nread == UV_ENOBUFS) { //alloc_buf() returned a buffer of length 0

        }

        uv_close((uv_handle_t*)stream, NULL);
    }
    else { //there is no more reading left
       
    }

    if (buf->base)
        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, on_read); //读取数据
    }
    else { //error
        uv_close((uv_handle_t*)client, NULL);
    }
}

int main()
{
    loop = uv_default_loop();

    uv_tcp_t server;
    uv_tcp_init(loop, &server); //初始化监听套接字

    sockaddr_in addr;
    uv_ip4_addr("0.0.0.0", 6000, &addr); //将ip地址和端口号转换为sockaddr_in结构,转换使用uv_ip4_name()
    uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0); //绑定IP地址和端口号

    int r = uv_listen((uv_stream_t*)&server, SOMAXCONN, on_new_connection); //设置监听模式,有新的连接到来时,调用回调函数on_new_connection
    if (r) {
        fprintf(stderr, "Listen error: %s\n", uv_strerror(r));
        return 1;
    }

    return uv_run(loop, UV_RUN_DEFAULT);
}

3、其它 

  libuv中实现TCP客户端、UDP应用、域名解析功能,可以参考:libuv中文教程—网络

 

posted on 2024-05-11 10:03  整鬼专家  阅读(8)  评论(0编辑  收藏  举报