libuv学习笔记(21)
来源:互联网 发布:购买海关数据 编辑:程序博客网 时间:2024/05/17 07:22
libuv学习笔记(21)
DNS相关功能
数据结构
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;struct uv_getaddrinfo_s { UV_REQ_FIELDS//uv_req_t的成员 uv_loop_t* loop; //UV_GETADDRINFO_PRIVATE_FIELDS展开: struct uv__work work_req;//线程池任务 uv_getaddrinfo_cb getaddrinfo_cb; void* alloc;//分配的内存的指针,方便释放 WCHAR* node; WCHAR* service; struct addrinfoW* addrinfow; struct addrinfo* addrinfo;//结果,需要通过uv_freeaddrinfo()释放 int retcode;};
typedef struct uv_getnameinfo_s uv_getnameinfo_t;struct uv_getnameinfo_s { UV_REQ_FIELDS//uv_req_t的成员 uv_loop_t* loop; //UV_GETNAMEINFO_PRIVATE_FIELDS展开: struct uv__work work_req; //线程池任务 uv_getnameinfo_cb getnameinfo_cb; struct sockaddr_storage storage;//保存询问的地址 int flags; char host[NI_MAXHOST]; char service[NI_MAXSERV]; int retcode;};
相关函数
`uv_getaddrinfo,获取地址信息
int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node,//主机名或ip地址 const char* service,//服务名或者端口 const struct addrinfo* hints) { int nodesize = 0; int servicesize = 0; int hintssize = 0; char* alloc_ptr = NULL; int err; if (req == NULL || (node == NULL && service == NULL)) { err = WSAEINVAL; goto error; } uv_req_init(loop, (uv_req_t*)req);//初始化请求 req->getaddrinfo_cb = getaddrinfo_cb; req->addrinfo = NULL; req->type = UV_GETADDRINFO; req->loop = loop; req->retcode = 0; //获取node与service的长度 //此处省略 // if (hints != NULL) { hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); } //申请内存 alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize); if (!alloc_ptr) { err = WSAENOBUFS; goto error; } req->alloc = (void*)alloc_ptr; //将node和service utf8转换为unicode //都存储在alloc_ptr指向的内存中 //此处省略 //此处省略 //将hints 的内容复制到req->addrinfow //此处省略 uv__req_register(loop, req); if (getaddrinfo_cb) {//有回调函数,那么走loop流程 uv__work_submit(loop, &req->work_req, uv__getaddrinfo_work,//调用GetAddrInfoW(req->node, req->service, hints, &req->addrinfow); uv__getaddrinfo_done);// return 0; } else {//没有回调函数,直接调用 uv__getaddrinfo_work(&req->work_req); uv__getaddrinfo_done(&req->work_req, 0); return req->retcode; }error: if (req != NULL) { uv__free(req->alloc); req->alloc = NULL; } return uv_translate_sys_error(err);}
获取信息之后loop调用的回调
static void uv__getaddrinfo_done(struct uv__work* w, int status) { uv_getaddrinfo_t* req; int addrinfo_len = 0; int name_len = 0; size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); struct addrinfoW* addrinfow_ptr; struct addrinfo* addrinfo_ptr; char* alloc_ptr = NULL; char* cur_ptr = NULL; req = container_of(w, uv_getaddrinfo_t, work_req); uv__free(req->alloc);//释放之前申请的内存 req->alloc = NULL; if (status == UV_ECANCELED) {//被取消的请求 assert(req->retcode == 0); req->retcode = UV_EAI_CANCELED; goto complete; } if (req->retcode == 0) { // 将addrinfoW转换为addrinfo //此处省略 //将名字转换为utf8 //此处省略 //释放req->addrinfow if (req->addrinfow != NULL) { FreeAddrInfoW(req->addrinfow); req->addrinfow = NULL; }complete: uv__req_unregister(req->loop, req); /* finally do callback with converted result */ if (req->getaddrinfo_cb)//调用用户的回调函数 req->getaddrinfo_cb(req, req->retcode, req->addrinfo);}
释放地址内存
void uv_freeaddrinfo(struct addrinfo* ai) { char* alloc_ptr = (char*)ai; uv__free(alloc_ptr);}
通过地址获取主机名
int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr,//地址 int flags) { if (req == NULL || addr == NULL) return UV_EINVAL; if (addr->sa_family == AF_INET) { memcpy(&req->storage, addr, sizeof(struct sockaddr_in)); } else if (addr->sa_family == AF_INET6) { memcpy(&req->storage, addr, sizeof(struct sockaddr_in6)); } else { return UV_EINVAL; } uv_req_init(loop, (uv_req_t*)req); uv__req_register(loop, req); req->getnameinfo_cb = getnameinfo_cb; req->flags = flags; req->type = UV_GETNAMEINFO; req->loop = loop; req->retcode = 0; if (getnameinfo_cb) { uv__work_submit(loop, &req->work_req, uv__getnameinfo_work,//调用GetNameInfoW uv__getnameinfo_done); return 0; } else { uv__getnameinfo_work(&req->work_req); uv__getnameinfo_done(&req->work_req, 0); return req->retcode; }}
loop回调
static void uv__getnameinfo_done(struct uv__work* w, int status) { uv_getnameinfo_t* req; char* host; char* service; req = container_of(w, uv_getnameinfo_t, work_req); uv__req_unregister(req->loop, req); host = service = NULL; if (status == UV_ECANCELED) { assert(req->retcode == 0); req->retcode = UV_EAI_CANCELED; } else if (req->retcode == 0) { host = req->host; service = req->service; } if (req->getnameinfo_cb)//回调用户回调函数 req->getnameinfo_cb(req, req->retcode, host, service);}
0 0
- libuv学习笔记(21)
- libuv学习笔记(2)
- libuv学习笔记(3)
- libuv学习笔记(4)
- libuv学习笔记(5)
- libuv学习笔记(6)
- libuv学习笔记(7)
- libuv学习笔记(9)
- libuv学习笔记(10)
- libuv学习笔记(11)
- libuv学习笔记(12)
- libuv学习笔记(13)
- libuv学习笔记(14)
- libuv学习笔记(16)
- libuv学习笔记(17)
- libuv学习笔记(18)
- libuv学习笔记(20)
- libuv学习笔记(22)
- 【Android开发经验】android:windowSoftInputMode属性详解
- CSS 元素垂直居中的 6种方法
- Android偏好设置存到哪里了?
- CXF实现webservice 解决list<map>类型转换
- 百度谷歌离线地图解决方案(离线地图下载)
- libuv学习笔记(21)
- Json 转 dynamic
- SceneKit:简单的3D游戏场景搭建
- 百度地图定位及跳到地图页面
- JAVA多线程和并发基础面试问答
- nrf24L01接收端只触发一次中断解决办法
- 开发restful风格的webservice
- 快速排序和插入排序
- 音频管理器 AudioManager