c_rpc_server::c_rpc_server(const unsigned short port) : m_io_service(), m_acceptor(m_io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string("127.0.0.1"), port)), m_socket(m_io_service), m_thread(), m_hmac_key() { m_hmac_key.fill(0x42); // TODO load this from conf file // start waiting for new connection m_acceptor.async_accept(m_socket, [this](boost::system::error_code error) { accept_handler(error); }); _dbg("Starting RPC server thread"); m_thread = std::thread([this]() { _dbg("RPC thread start"); try { boost::system::error_code ec; _dbg("io_service run"); m_io_service.run(ec); _dbg("end of io_service run"); if (ec) _dbg("error code " << ec.message()); _dbg("io_service reset"); m_io_service.reset(); } catch (const std::exception &e) { _dbg("io_service exception" << e.what()); } catch (...) { _dbg("catch unhandled exception"); } _dbg("RPC thread stop"); }); // lambda }
void c_rpc_server::accept_handler(const boost::system::error_code &error) { _dbg("Connected"); if (!error) { LockGuard<Mutex> lg(m_session_vector_mutex); m_session_list.emplace_back(this, std::move(m_socket), m_hmac_key); m_session_list.back().set_iterator_in_session_list(--m_session_list.end()); } // continue waiting for new connection m_acceptor.async_accept(m_socket, [this](boost::system::error_code error) { accept_handler(error); }); }
inline void rawsocket_listener::handle_accept( const boost::system::error_code &error_code) { if (error_code) { return; } assert(get_accept_handler()); const auto& accept_handler = get_accept_handler(); accept_handler(create_connection()); async_accept(); }
int start_accept(http_conf *g) { int count; struct epoll_event ev[MAX_EVENT]; epoll_extra_data_t *epoll_data; start_web_server(g); printf("--------------- start server\n--------------"); while(1){ count = epoll_wait(g->epfd, ev, MAX_EVENT, -1); while(count-- > 0){ epoll_data = (epoll_data_t *)ev[count].data.ptr; if(epoll_data->type == SERVERFD) { int confd = accept(g->fd, NULL, NULL); pool_t *p = (pool_t *)pool_create(); http_connect_t * con; epoll_extra_data_t *data_ptr; data_ptr = (epoll_extra_data_t *)palloc(p, sizeof(epoll_extra_data_t)); con = (http_connect_t *) palloc(p, sizeof(http_connect_t));//换成初始化函数, con->p= p; con->fd = confd; data_ptr->type = SOCKFD; data_ptr->ptr = (void *) con; epoll_add_fd(g->epfd, confd, EPOLL_R, (void *)data_ptr);//对epoll data结构指向的结构体重新封装,分websit //data struct , connect data struct , file data struct , } else if((ev[count].events & EPOLLIN)) { http_connect_t * con; con = (http_connect_t *) epoll_data->ptr; switch(epoll_data->type) { case SOCKFD: if(con->in == NULL) { accept_handler(g, con, ev+count); } if(con->next_handle != NULL) { con->next_handle(con); } else { epoll_del_fd(g->epfd, ev); close(con->fd); pool_destroy(con->p); } break; case CGIFD: { epoll_cgi_t *cgi = (epoll_cgi_t *)epoll_data->ptr; break; } } } else if(ev[count].events & EPOLLOUT) { } } } }
int start_accept(http_conf_t *conf) { int count; struct epoll_event ev[MAX_EVENT]; epoll_extra_data_t *epoll_data; struct epoll_event * evfd; int evIndex ; start_web_server(conf); printf("--------------- start server\n--------------"); while(1){ count = epoll_wait(conf->epfd, ev, MAX_EVENT, -1); http_accept_request_socket(conf, conf->fd); if(count < 0) { count = 0;} for(evIndex = 0; evIndex < count; evIndex++) { evfd = ev + evIndex; epoll_data = (epoll_extra_data_t *)evfd->data.ptr; if(epoll_data->type != SERVERFD && (evfd->events & EPOLLIN)) { http_connect_t * con; con = (http_connect_t *) epoll_data->ptr; switch(epoll_data->type) { case SOCKFD: accept_handler(conf, con, evfd); break; case CGIFD: { epoll_cgi_t *cgi = (epoll_cgi_t *)epoll_data->ptr; if(read_cgi(cgi) == 0) { list_buffer_used_to_zero(cgi->cgi_data); if(cgi_parse_handler(cgi) == 0) { } else { } epoll_del_fd(conf->epfd, evfd); pool_destroy(cgi->con->p); close(cgi->con->fd); } else { } break; } case SERVERFD: //有多个web配置的时候可用 以后测试 //http_accept_request_socket(g, con->fd); //接受连接 break; } } else if(evfd->events & EPOLLOUT) { }else if(evfd->events & EPOLLRDHUP) { http_connect_t * con; epoll_data = (epoll_data_t *)evfd->data.ptr; con = (http_connect_t *) epoll_data->ptr; if(con->in != NULL) { epoll_edit_fd(conf->epfd, evfd, EPOLL_W); pool_destroy(con->p); close(con->fd); } con->next_handle = NULL; epoll_del_fd(conf->epfd, evfd); } } } }
int rf_epoll_wait(epoll_handle_accept *accept_handler,epoll_handle_read_event *read_handler,epoll_handle_write_event *write_handler){ int nfds; int i; rf_client *rfc; nfds = epoll_wait(kdpfd, events, MAX_EVENTS, EPOLL_TIMEOUT); if(nfds == -1) { if( errno != EINTR ) { cclog(2,"ERROR. {%s}\n", strerror(errno)); return RF_ERR_EPOLL; } return RF_OK; } else if( 0 == nfds) { cclog(9,"epoll timeout!"); return RF_OK; } int ret = -1; int fd; for( i = 0 ; i < nfds ; i++ ) { if( listen_fd == events[i].data.fd ) { accept_handler(listen_fd); continue; } fd = events[i].data.fd; rfc = &fd_table[fd]; if(events[i].events & (EPOLLIN|EPOLLHUP|EPOLLERR)){ ret = read_handler(fd); switch(ret){ case RF_OK: cclog(5,"process success! fd(%d)",fd); break; case RF_ERR_PEER_CLOSE: cclog(2,"close peer socket! close fd(%d),ip(%s)",fd,get_peer_ip(fd)); //add for async report dir refresh result if(rfc->type == RF_CLIENT_REPORT) { rf_set_session_report_status(fd, RF_SESSION_CLOSE); } //add for async report dir refresh result disconnect_fd(fd); break; case RF_CLOSE_REPORT: if(rfc->type == RF_CLIENT_REPORT) { cclog(2, "refreshd close report fd: [%d], peer_ip: [%s]", fd, get_peer_ip(fd)); rf_set_session_report_status(fd, RF_SESSION_SUCCESS); } disconnect_fd(fd); break; default: //add for async report dir refresh result if(rfc->type == RF_CLIENT_REPORT) { rf_set_session_report_status(fd, RF_SESSION_FAILED); } //add for async report dir refresh result cclog(2,"proccess error! close fd(%d),ip(%s),ret(%d)",fd,get_peer_ip(fd),ret); disconnect_fd(fd); break; } } if(events[i].events & (EPOLLOUT|EPOLLHUP|EPOLLERR)){ ret = write_handler(fd); switch(ret){ case RF_OK: cclog(5,"process success! fd(%d),ip(%s)",fd,get_peer_ip(fd)); break; case RF_ERR_PEER_CLOSE: cclog(2,"close peer socket! close fd(%d),ip(%s)",fd,get_peer_ip(fd)); //add for async report dir refresh result if(rfc->type == RF_CLIENT_REPORT) { rf_set_session_report_status(fd, RF_SESSION_SUCCESS); } //add for async report dir refresh result disconnect_fd(fd); break; default: //add for async report dir refresh result rfc = &fd_table[fd]; if(rfc->type == RF_CLIENT_REPORT) { rf_set_session_report_status(fd, RF_SESSION_FAILED); } //add for async report dir refresh result cclog(2,"proccess error! close fd(%d),ip(%s)",fd,get_peer_ip(fd)); disconnect_fd(fd); break; } } } return RF_OK; }