// 调用 service_.rpc_fork 后,由 RPC 框架在子线程中调用本函数 // 来处理本地其它模块发来的请求信息 void http_rpc::rpc_run() { // 打开阻塞流对象 acl::socket_stream stream; // 必须用 get_vstream() 获得的 ACL_VSTREAM 流对象做参数 // 来打开 stream 对象,因为在 acl_cpp 和 acl 中的阻塞流 // 和非阻塞流最终都是基于 ACL_VSTREAM,而 ACL_VSTREAM 流 // 内部维护着了一个读/写缓冲区,所以在长连接的数据处理中, // 必须每次将 ACL_VSTREAM 做为内部流的缓冲流来对待 ACL_VSTREAM* vstream = client_->get_vstream(); ACL_VSTREAM_SET_RWTIMO(vstream, 10); (void) stream.open(vstream); rpc_req_add(); // 开始处理该 HTTP 请求 handle_conn(&stream); rpc_req_del(); // 将 ACL_VSTREAM 与阻塞流对象解绑定,这样才能保证当释放阻塞流对象时 // 不会关闭与请求者的连接,因为该连接本身是属于非阻塞流对象的,需要采 // 用异步流关闭方式进行关闭 stream.unbind(); }
void SocketServer::handleCommunication() { struct sockaddr_in client_addr; unsigned int client_addr_len = sizeof(client_addr); signal(SIGCHLD, SIG_IGN); // We are not interested in results from the children while (1) { // get next incoming connection, block if none int newsockfd = accept(sockfd, (struct sockaddr *) &client_addr, &client_addr_len); if (newsockfd < 0) error("ERROR, could not retrieve incoming connection"); int pid = fork(); // new process for every connection if (pid < 0) error("ERROR, could not fork process"); if (pid == 0) { // child close(sockfd); std::cout << "New client connection assigned to process " << getpid() << std::endl; handle_conn(newsockfd); exit(0); } else // parent { close(newsockfd); } } }
void ShmemServer::handleCommunication() { sem_wait(shmem_force_order_sem); // wait for client to connect sem_wait(shmem_sem); sem_post(shmem_force_order_sem); handle_conn(); }
void sigio(int sock) { int nsock; while((nsock = accept(sock, NULL, NULL)) != -1) { if(nsock == -1) { if(errno != EAGAIN) { perror("accept"); } return; } handle_conn(nsock); } }
void broker_on_data_callback(Client *client, void *data) { Broker *broker = data; RemoteDSLink *link = client->sock_data; if (link) { link->ws->read_enabled = 1; wslay_event_recv(link->ws); if (link->pendingClose) { broker_close_link(link); } return; } HttpRequest req; char buf[1024]; { int read = dslink_socket_read(client->sock, buf, sizeof(buf) - 1); buf[read] = '\0'; broker_http_parse_req(&req, buf); } if (strcmp(req.uri.resource, "/conn") == 0) { if (strcmp(req.method, "POST") != 0) { log_info("invalid method on /conn \n"); broker_send_bad_request(client->sock); goto exit; } handle_conn(broker, &req, client->sock); } else if (strcmp(req.uri.resource, "/ws") == 0) { if (strcmp(req.method, "GET") != 0) { log_info("invalid method on /ws \n"); broker_send_bad_request(client->sock); goto exit; } handle_ws(broker, &req, client); return; } else { broker_send_not_found_error(client->sock); } exit: dslink_socket_close_nofree(client->sock); }
/* * MAIN */ int main(int argc, char *argv[]) { int sock_fd; int err; int optval; int conn; struct sockaddr_in *addr, *client_addr; socklen_t client_addr_size; struct hsearch_data *htab; pthread_t thread; thdata *thread_data = malloc(sizeof(thdata)); // Create hashmap storage htab = calloc(1, sizeof(struct hsearch_data)); if (hcreate_r(10000, htab) == -1) { printf("Error on hcreate\n"); } // Create socket sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd == -1) { printf("Error creating socket: %d\n", errno); } // Allow address reuse optval = 1; err = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)); if (err == -1) { printf("Error setting SO_REUSEADDR on socket: %d\n", errno); } // bind addr = calloc(1, sizeof(struct sockaddr_in)); addr->sin_family = AF_INET; addr->sin_port = htons(11211); // htons: Convert to network byte order addr->sin_addr.s_addr = INADDR_ANY; err = bind(sock_fd, (struct sockaddr *)addr, sizeof(struct sockaddr)); free(addr); if (err == -1) { printf("bind error: %d\n", errno); } err = listen(sock_fd, 1); if (err == -1) { printf("listen error: %d\n", errno); } if (is_single(argc, argv)) { client_addr = malloc(sizeof(struct sockaddr_in)); client_addr_size = sizeof(struct sockaddr); conn = accept(sock_fd, (struct sockaddr *)client_addr, &client_addr_size); free(client_addr); thread_data->conn = conn; thread_data->htab = htab; handle_conn(thread_data); close(conn); } else { while (1) { client_addr = malloc(sizeof(struct sockaddr_in)); client_addr_size = sizeof(struct sockaddr); conn = accept( sock_fd, (struct sockaddr *)client_addr, &client_addr_size); free(client_addr); thread_data->conn = conn; thread_data->htab = htab; pthread_create( &thread, NULL, handle_conn, thread_data); } } close(sock_fd); free(thread_data); hdestroy_r(htab); free(htab); return 0; }