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