异步请求池的实现

简介: 异步请求池的实现

1.一个连接还是多个连接?          多个

2.网络IO的基础,发送对应的协议。

3.既然是多个连接,发送完请求后,响应没有接收以前,fd存储在哪里?    

             fd由epoll进行管理,只关心可读事件,说明数据库返回了。

4. 请求与响应的数据不能做到一个线程。

如何设计

typedef void (*async_result_cb)(struct dns_item *arg, int count);
struct async_context {
  int epfd;
  pthread_t threadid;
};
struct ep_arg {
  int sockfd;
  async_result_cb cb;
};
#define ASYNC_EVENTS    128
void *dns_async_callback(void *arg) {
  struct async_context* ctx = (struct async_context*)arg;
  while (1) {
    struct epoll_event events[ASYNC_EVENTS] = {0};
    int nready = epoll_wait(ctx->epfd, events, ASYNC_EVENTS, -1);
    if (nready < 0) {
      continue;
    }
    int i = 0;
    for (i = 0;i < nready;i ++) {
      struct ep_arg *ptr = events[i].data.ptr;
      int sockfd = ptr->sockfd;
      char buffer[1024] = {0};
      struct sockaddr_in addr;
      size_t addr_len = sizeof(struct sockaddr_in);
      int n = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, (socklen_t*)&addr_len);
      printf("recvfrom n : %d\n", n);
      struct dns_item *domains = NULL;
      int count = dns_parse_response(buffer, &domains);
      ptr->cb(domains, count);
      // sockfd 
      close (sockfd);
      free(ptr);
      // epollout --> 
      //epoll_ctl(ctx->epfd, EPOLL_CTL_MOD, sockfd, NULL);  
    }
  }
}
// 1 . context 
// 2 . return context;
// 
struct async_context* dns_async_client_init(void) {
  int epfd = epoll_create(1);
  if (epfd < 0) return NULL;
  struct async_context* ctx = calloc(1, sizeof(struct async_context));
  if (ctx == NULL) return NULL;
  ctx->epfd = epfd;
  int ret = pthread_create(&ctx->threadid, NULL, dns_async_callback, ctx);
  if (ret) {
    close(epfd);
    free(ctx);
    return NULL;
  }
  return ctx;
}
int dns_async_client_destroy(struct async_context* ctx) {
  close(ctx->epfd);
  pthread_cancel(ctx->threadid);
} 
int dns_async_client_commit(struct async_context *ctx, async_result_cb cb) {
  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockfd < 0) {
    perror("create socket failed\n");
    exit(-1);
  }
  printf("url:%s\n", domain);
  struct sockaddr_in dest;
  bzero(&dest, sizeof(dest));
  dest.sin_family = AF_INET;
  dest.sin_port = htons(53);
  dest.sin_addr.s_addr = inet_addr(DNS_SVR);
  int ret = connect(sockfd, (struct sockaddr*)&dest, sizeof(dest));
  printf("connect :%d\n", ret);
  struct dns_header header = {0};
  dns_create_header(&header);
  struct dns_question question = {0};
  dns_create_question(&question, domain);
  char request[1024] = {0};
  int req_len = dns_build_request(&header, &question, request);
  int slen = sendto(sockfd, request, req_len, 0, (struct sockaddr*)&dest, sizeof(struct sockaddr));
  struct ep_arg *ptr = calloc(1, sizeof(struct ep_arg));
  if (ptr == NULL) return -1;
  ptr->sockfd = sockfd;
  ptr->cb = cb;
  //
  struct epoll_event ev;
  ev.data.ptr = ptr;
  ev.events = EPOLLIN;
  epoll_ctl(ctx->epfd, EPOLL_CTL_ADD, sockfd, &ev);
  return 0;
}

 

目录
相关文章
|
22天前
|
网络协议 NoSQL 关系型数据库
池式组件-异步请求池的原理与实现
池式组件-异步请求池的原理与实现
27 0
|
7月前
|
网络协议 NoSQL 关系型数据库
异步请求池
异步请求池
84 0
|
17天前
|
存储 中间件 API
中间件应用程序发起读取数据的请求
【5月更文挑战第12天】中间件应用程序发起读取数据的请求
25 4
|
22天前
|
网络协议 NoSQL 测试技术
异步请求池的实现
异步请求池的实现
37 0
|
10月前
|
小程序
小程序接口请求配置
小程序接口请求配置
151 0
|
22天前
|
域名解析 网络协议
异步请求池原理及实现
异步请求池原理及实现
|
22天前
|
安全 Java
C++11的半同步半异步线程池
C++11的半同步半异步线程池
47 0
|
22天前
|
JSON 前端开发 JavaScript
关于我认识的请求方式
关于我认识的请求方式有三个
44 0
|
7月前
|
网络协议 测试技术
异步请求池——池式组件
异步请求池——池式组件
|
8月前
|
JSON NoSQL 安全
后端如何优雅地处理重复请求/并发请求?
后端如何优雅地处理重复请求/并发请求?
227 0

热门文章

最新文章