void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { if (gpr_unref(&s->refs)) { /* Complete shutdown_starting work before destroying. */ grpc_exec_ctx local_exec_ctx = GRPC_EXEC_CTX_INIT; grpc_closure_list_sched(&local_exec_ctx, &s->shutdown_starting); if (exec_ctx == NULL) { grpc_exec_ctx_flush(&local_exec_ctx); tcp_server_destroy(&local_exec_ctx, s); grpc_exec_ctx_finish(&local_exec_ctx); } else { grpc_exec_ctx_finish(&local_exec_ctx); tcp_server_destroy(exec_ctx, s); } } }
void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { if (gpr_unref(&s->refs)) { grpc_tcp_server_shutdown_listeners(exec_ctx, s); gpr_mu_lock(&s->mu); grpc_exec_ctx_enqueue_list(exec_ctx, &s->shutdown_starting, NULL); gpr_mu_unlock(&s->mu); tcp_server_destroy(exec_ctx, s); } }
int rpc_start(struct rpc *rpc) { tcp_server_t *tcpserver = NULL; struct timeval timeout; /* タイムアウト値の設定 */ timeout.tv_sec = rpc->rpc_timeout; timeout.tv_usec = 0; /* TCPサーバーの生成 */ if (tcp_server_create( &tcpserver, NULL, rpc->bind_port, RECV_BUFF, EV_READ, &timeout, rpc_accept_init, rpc_accept_main, rpc_accept_finish, rpc_listen_init, rpc_listen_finish, rpc, rpc->event_base)) { fprintf(stderr, "failed in create tcp server instance.\n"); return 1; } rpc->tcpserver = tcpserver; /* * TCPサーバーの開始 * イベントループで回る */ if (tcp_server_start(rpc->tcpserver)) { fprintf(stderr, "failed in start up tcp server instance.\n"); rpc->tcpserver = NULL; } /* * TCPサーバーの削除 */ tcp_server_destroy(rpc->tcpserver); rpc->tcpserver = NULL; printf("tcp server end.\n"); return 0; }
tcp_server_t *tcp_server_create(int port, int max_conn) { tcp_server_t *server = NULL; tcp_server_stream_t *stream = NULL; int max_conn_count = TCP_MAX_STREAM_NUM; int i = 0; struct sockaddr_in server_addr; struct epoll_event event; server = (tcp_server_t *)malloc(sizeof(tcp_server_t)); if (NULL == server) { goto error; } bzero(server, sizeof(tcp_server_t)); server->rcv_cb = rcv_cb_default; server->snd_cb = snd_cb_default; server->port = port; if (max_conn > 0) { max_conn_count = max_conn; } /* 创建并发连接结构 */ server->streams = (tcp_server_stream_t *)malloc(sizeof(tcp_server_stream_t) * max_conn_count); if (NULL == server->streams) { log_error("malloc for server->streams failed."); goto error; } bzero(server->streams, sizeof(tcp_server_stream_t) * max_conn_count); server->stream_num = max_conn_count; /* idle stream链表初始化 */ for (i = 0; i < max_conn_count; i++) { server->streams[i].index = i; add_stream_into_idle_list(server, &server->streams[i]); } /* 创建listen socket */ server->listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (-1 == server->listen_fd) { log_error("create socket failed, %s", strerror(errno)); goto error; } /* 设置为非阻塞 */ if (!set_non_blocking(server->listen_fd)){ log_error("set_non_blocking failed."); goto error; } /* 设置地址重用 */ if (!set_reuse_addr(server->listen_fd)) { log_error("set reuse addr failed."); goto error; } /* 绑定端口 */ bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(server->port); if (bind(server->listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { log_error("bind server addr failed, %s", strerror(errno)); goto error; } /* 设置监听 */ if (listen(server->listen_fd, TCP_MAX_LISTEN_NUM) < 0) { log_error("listen failed, %s", strerror(errno)); goto error; } /* 创建epoll句柄 */ server->epoll_fd = epoll_create(TCP_MAX_CONNECT_NUM); if (server->epoll_fd < 0) { log_error("epoll_create failed, %s", strerror(errno)); goto error; } /* 获取空闲的stream */ stream = get_idle_tcp_stream(server); if (NULL == stream) { log_error("get_idle_tcp_stream for listen stream failed."); goto error; } /* 将listen fd加入epoll */ bzero(&event, sizeof(event)); event.data.fd = server->listen_fd; event.data.ptr = stream; event.events = EPOLLIN | EPOLLET; /* 创建listen stream */ tcp_stream_init(server, stream, server->listen_fd, NULL); stream->snd_cb = NULL; stream->rcv_cb = accept_cb; add_stream_into_busy_list(server, stream); return server; error: tcp_server_destroy(server); return NULL; }
int main(int argc, char** argv) { char path[50] = { 0x00 }; if (2 <= argc) { strncpy(path, argv[1], strlen(argv[1])); } else { strncpy(path, "server.cfg", 10); } //读取配置文件 TinyConf* config; char* run; for(;;) { config = conf_open(path, '='); if(NULL == config) { sleep(5); continue; } run = conf_get(config, "run"); if(0 >= strlen(run)) { sleep(5); continue; } if(0 != strcmp(run, "on")) { sleep(5); continue; } break; //一切ok,启动正常处理 } //初始化mysql配置 char* mysql_host = conf_get(config, "mysql_host"); char* mysql_port_str = conf_get(config, "mysql_port"); char* mysql_user = conf_get(config, "mysql_user"); char* mysql_password = conf_get(config, "mysql_password"); char* mysql_database = conf_get(config, "mysql_database"); //将数据库设置存入到map中 TinyMap* store_map = map_create(); map_add(store_map, "host", mysql_host, NULL); map_add(store_map, "port", mysql_port_str, NULL); map_add(store_map, "user", mysql_user, NULL); map_add(store_map, "password", mysql_password, NULL); map_add(store_map, "database", mysql_database, NULL); //初始化tcpserver的相关代码 int tcp_port = 7000; char* tcp_port_str = conf_get(config, "port"); if(0 < strlen(tcp_port_str)) { tcp_port = atoi(tcp_port_str); } TCPServer* tcp_server = tcp_server_create(tcp_port); //生成tcp服务器实例 if(NULL == tcp_server) { fprintf(stderr, "Create server falied.\n"); } tcp_server_set_proc_callback(tcp_server, store_map, analyze_proc); //注册数据处理的回调函数 tcp_server_set_timeout_callback(tcp_server, store_map, analyze_timeout); //注册客户端连接超时的回调函数 int ret = tcp_server_start(tcp_server); //启动tcp服务器 if(-1 == ret) { fprintf(stderr, "Start tcpserver falied.\n"); return 0; } //创建存储实例 Store* store = store_create(mysql_host, atoi(mysql_port_str), mysql_user, mysql_password, mysql_database); //创建网络检测线程 pthread_t thread_id; int p_ret = pthread_create(&thread_id, NULL, (void*)check_networks, store); if(0 != p_ret) { fprintf(stderr, "%s\n", "create networks check thread err."); } for(;;) { //阻塞 sleep(1000); } pthread_cancel(thread_id); //退出线程 store_destroy(store); //销毁存储实例 tcp_server_stop(tcp_server); //停止tcp服务器实例 tcp_server_destroy(tcp_server); //销毁tcp服务器实例 map_destroy(store_map); //销毁store_map实例 conf_close(config); //关闭配置信息读取实例 return 0; }