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; }