/* ======================================= 工作线程 ======================================= */ CR_API uint_t STDCALL qst_com_main ( __CR_IN__ void_t* param ) { exec_t obj; sQstComm* ctx; /* 加载命令表 */ obj = cmd_exec_init(s_cmdz, cntsof(s_cmdz)); if (obj == NULL) { qst_com_app_exit(param, 0, NULL); return (QST_ERROR); } ctx = (sQstComm*)param; /* 工作循环 */ while (!ctx->quit) { ansi_t* string; /* 接收一条命令 */ /* 即使是出错也要继续运行 */ string = netw_cmd_recv(ctx->netw); if (string == NULL) { thread_sleep(1); continue; } /* 非命令直接交由发送函数处理 */ if (!cmd_type_okay(string) && ctx->comm.thrd != NULL) { if (ctx->comm.send != NULL) { if (ctx->comm.tran == NULL) { /* 直接发送 */ ctx->comm.send(ctx->comm.obj.parm, string, str_lenA(string)); } else { uint_t size; void_t* send; /* 变换后发送 */ send = ctx->comm.tran(string, &size); if (send != NULL) { ctx->comm.send(ctx->comm.obj.parm, send, size); mem_free(send); } } } mem_free(string); continue; } /* 执行这条命令 */ cmd_exec_main(obj, ctx, string); mem_free(string); } /* 等待通讯线程结束 */ if (ctx->comm.thrd != NULL) { ctx->comm.quit = TRUE; thread_wait(ctx->comm.thrd); thread_del(ctx->comm.thrd); } cmd_exec_free(obj); return (QST_OKAY); }
/* ======================================= 主程序 ======================================= */ int main (int argc, char *argv[]) { CR_NOUSE(argc); CR_NOUSE(argv); /* 建立 CrHack 系统 */ if (!set_app_type(CR_APP_CUI)) return (QST_ERROR); SetConsoleTitleA(WIN_TITLE); sint_t x1, y1; uint_t ww, hh; /* 初始化窗口 */ s_hcui = GetStdHandle(STD_OUTPUT_HANDLE); if (s_hcui == INVALID_HANDLE_VALUE) return (QST_ERROR); s_hwnd = GetConsoleWindow(); if (s_hwnd == NULL) return (QST_ERROR); misc_desk_init(WIN_ICONF, &x1, &y1, &ww, &hh, QSRV_DEF_WIDTH, QSRV_DEF_HEIGHT); misc_cui_setwin(s_hwnd, s_hcui, x1, y1, ww, hh); sINIu* ini; uint_t temp; ansi_t* text; int16u port = QST_DEF_PORT; ansi_t* addr = QST_DEF_ADDR; uint_t count = QST_DEF_CLIENT; /* 读取参数 */ text = file_load_as_strA(QST_CFG_STARTUP); if (text != NULL) { ini = ini_parseU(text); mem_free(text); text = NULL; if (ini != NULL) { text = ini_key_stringU("serv::bind", ini); if (text != NULL) addr = text; temp = ini_key_intxU("serv::port", QST_DEF_PORT, ini); if (temp > 1024 && temp < 32768) port = (int16u)temp; temp = ini_key_intxU("serv::count", QST_DEF_CLIENT, ini); if (temp > 0 && temp <= QST_MAX_CLIENT) count = temp; ini_closeU(ini); } } socket_t serv; sQstWork* work; /* 建立工作单元组 */ work = qst_wrk_create(count); if (work == NULL) return (QST_ERROR); /* 初始化网络 */ if (!socket_init()) return (QST_ERROR); serv = server_tcp_open(addr, port); TRY_FREE(text); if (serv == NULL) return (QST_ERROR); /* 初始化锁 */ mtlock_init(&s_qst_lck_shw); mtlock_init(&s_qst_lck_wrk); int16u logo_color; /* 建立颜色值 */ logo_color = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED | CR_CUI_TEXT_BLUE); s_qst_clr_cin = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN | CR_CUI_TEXT_RED); s_qst_clr_say = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_GREEN); s_qst_clr_out = cui_make_attr(0, CR_CUI_TEXT_LIGHT | CR_CUI_TEXT_RED); /* 工作循环 */ cui_set_color(logo_color); printf("######################################\n"); printf("## QUESTLAB BROADCAST SERVER ##\n"); printf("######################################\n"); while (!s_quit) { ansi_t* ptr; bool_t okay; ansi_t* name; socket_t netw; /* 接受一个客户端 */ netw = server_tcp_accept(serv); if (netw == NULL) continue; /* 接收客户端名称 */ socket_set_timeout(netw, -1, QST_TCP_TOUT); name = netw_cmd_recv(netw); if (name == NULL) { socket_close(netw); continue; } /* 客户端名称过滤 */ if (str_lenA(name) > QST_MAX_NAME) { netw_ack_send(netw, FALSE); netw_cli_close(netw); mem_free(name); continue; } ptr = name; okay = TRUE; while (*ptr != NIL) { if (is_cntrlA(*ptr++)) { okay = FALSE; break; } } if (!okay) { netw_ack_send(netw, FALSE); netw_cli_close(netw); mem_free(name); continue; } /* 启动一个工作单元 */ if (!qst_wrk_wakeup(work, name, netw, qst_srv_main)) { netw_cli_close(netw); mem_free(name); continue; } } return (QST_OKAY); }