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中文教程—网络。