From 01abbffa9120e862704d918cae43de882f6c4ad8 Mon Sep 17 00:00:00 2001 From: Saturneric Date: Tue, 5 Mar 2019 13:03:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/instruct.h | 1 + include/net.h | 9 +++- include/server.h | 1 + src/controller.cpp | 113 +++++++++++++++++++++++++++++++++++++++++---- src/model.cpp | 72 ++++++++++++++++++++++++++++- src/server.cpp | 11 ++--- 6 files changed, 190 insertions(+), 17 deletions(-) diff --git a/include/instruct.h b/include/instruct.h index f3ca59f..91d6cc0 100644 --- a/include/instruct.h +++ b/include/instruct.h @@ -42,6 +42,7 @@ int set(string instruct, vector &configs, vector &lconfigs, vect bool config_search(vector &configs,string tfg); void getSQEPublicKey(respond *pres,void *args); void registerSQECallback(respond *pres,void *args); +void loginSQECallback(respond *pres, void *args); void* connectionDeamon(void *args); //客户端连接管理守护进程 void *clientServiceDeamon(void *); diff --git a/include/net.h b/include/net.h index bd100f1..ef6dc64 100644 --- a/include/net.h +++ b/include/net.h @@ -149,7 +149,11 @@ public: if(!~server_sfd) throw "fail to get server sfd"; // 绑定IP地址与端口 if(!~bind(server_sfd, server_addr.RawObj(), server_addr.Size())) throw "fail to bind"; -// 设置接受信息非阻塞 + + //设置超时 + struct timeval timeout = { 3,0 }; + setsockopt(server_sfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)); + } SocketTCPCServer(void):SocketServer(){ data_sfd = -1; @@ -194,6 +198,9 @@ public: //send_addr.SetPort(9053); // 建立TCP连接 if(connect(client_sfd,send_addr.RawObj(),send_addr.Size()) < 0) throw "fail to connect"; + struct timeval timeout = { 3,0 }; + //设置超时 + setsockopt(client_sfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)); } // 发送简单字符串数据 void Send(string str); diff --git a/include/server.h b/include/server.h index 0944d30..37fb842 100644 --- a/include/server.h +++ b/include/server.h @@ -244,6 +244,7 @@ struct connection_listener{ void *write_buff = nullptr; struct connection_info *p_ci = nullptr; pthread_t *beat_pid = nullptr, *listen_pid = nullptr, *send_pid = nullptr; + sqlite3 *psql; }; //通用服务器类 diff --git a/src/controller.cpp b/src/controller.cpp index 808771a..e9f745a 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -478,10 +478,58 @@ int client(string instruct, vector &configs, vector &lconfigs, v } int if_find = sqlite3_column_int(psqlsmt, 0); if (if_find) { + error::printInfo("Doing Login"); //如果本地已经有注册信息 + string reqstr = " {\"passwd\":null, \"client_id\":null}"; + string sql_quote = "SELECT * from client_register_info where rowid = 1;"; + sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); + sqlite3_step(psqlsmt); + int status = sqlite3_column_int(psqlsmt, 5); + if (status == 1) { + error::printSuccess("[GET INFO]"); + uint64_t client_id = sqlite3_column_int64(psqlsmt, 0); + uint64_t passwd = sqlite3_column_int64(psqlsmt, 4); + string name = (const char *)sqlite3_column_text(psqlsmt, 1); + string tag = (const char *)sqlite3_column_text(psqlsmt, 2); + + aes_key256 naeskey; + const void *key_buff = sqlite3_column_blob(psqlsmt, 3); + memcpy(naeskey.key, key_buff, sizeof(uint64_t) * 4); + nclt.SetAESKey(naeskey); + + error::printInfo("Client_ID: " + std::to_string(client_id)); + error::printInfo("Passwd: " + std::to_string(passwd)); + error::printInfo("Name: " + name); + error::printInfo("Tag: " + tag); + + request *pnreq; + nclt.NewRequest(&pnreq, msqe_ip, msqe_port, "client login", "", true); + pnreq->JsonParse(reqstr); + pnreq->req_doc["client_id"].SetInt64(client_id); + pnreq->req_doc["passwd"].SetInt64(passwd); + pnreq->Json2Data(); + + nclt.NewRequestListener(pnreq, 44, psql, loginSQECallback); + //等待主广场服务器回应 + if_wait = 1; + while (if_wait == 1) { + sleep(1); + } + //成功注册 + if (!if_wait) { + + } + + } + else { + error::printError("Register information is broken. Strat to do register."); + if_find = 0; + } + sqlite3_finalize(psqlsmt); } - else { + if(!if_find){ + error::printInfo("Doing Register"); //如果本地没有注册信息 //向主广场服务器注册 aes_key256 naeskey; @@ -533,21 +581,45 @@ int client(string instruct, vector &configs, vector &lconfigs, v while (if_wait == 1) { sleep(1); } + //成功注册 + if (!if_wait) { + sqlite3_stmt *psqlsmt; + sql::insert_info(psql, &psqlsmt, "client_register_info", { + {"name","?1"}, + {"tag","?2"}, + {"key","?3"}, + {"status","0"}, + }); + sqlite3_bind_text(psqlsmt, 1, nclt.name.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(psqlsmt, 2, nclt.tag.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_blob(psqlsmt, 3, nclt.post_key.GetKey(), sizeof(uint64_t) * 4, SQLITE_TRANSIENT); + sqlite3_step(psqlsmt); + sqlite3_finalize(psqlsmt); + } + else if (~!if_wait) { + error::printError("fail to do register."); + return -1; + } } //得到服务器回应 if (!if_wait) { -// 成功注册 +// 成功注册或者登录 printf("Get Respond From Server.\n"); + sqlite3_close(psql); + // 创建守护进程 int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT); if(shmid == -1){ printf("SHMAT Failed.\n"); } + pid_t fpid = fork(); if(fpid == 0){ //守护进程 printf("Client Register Deamon Has Been Created.\n"); + sqlite3 *psql; + sqlite3_open("info.db", &psql); nclt.server_cnt = new SocketTCPCServer(9052); nclt.server_cnt->Listen(); @@ -569,6 +641,7 @@ int client(string instruct, vector &configs, vector &lconfigs, v pncl->listen_pid = &listen_pid; pncl->send_pid = &send_pid; pncl->p_ci = new connection_info(); + pncl->psql = psql; pthread_create(&pncl->pid, NULL, clientServiceDeamon, pncl); @@ -642,14 +715,38 @@ int client(string instruct, vector &configs, vector &lconfigs, v memcpy(&n_ci, buff + sizeof(uint32_t), sizeof(connection_info)); memset(buff, 0, sizeof(uint32_t)); printf("STATUS:\n"); - if (n_ci.if_beat) error::printSuccess("*Beat"); - else error::printRed("*Beat"); - if (n_ci.if_listen) error::printSuccess("*Listen"); - else error::printRed("*Listen"); - if (n_ci.if_send) error::printSuccess("*Send"); - else error::printRed("*Send"); + if (n_ci.if_beat) error::printSuccess("(*)Beat"); + else error::printRed("(*)Beat"); + if (n_ci.if_listen) error::printSuccess("(*)Listen"); + else error::printRed("(*)Listen"); + if (n_ci.if_send) error::printSuccess("(*)Send"); + else error::printRed("(*)Send"); + } + else if (cmdstr == "info") { + sqlite3_open("info.db",&psql); + string sql_quote = "SELECT * from client_register_info where rowid = 1;"; + sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); + sqlite3_step(psqlsmt); + int status = sqlite3_column_int(psqlsmt, 5); + if (status == 1) { + error::printSuccess("[GET INFO]"); + uint64_t client_id = sqlite3_column_int64(psqlsmt, 0); + uint64_t passwd = sqlite3_column_int64(psqlsmt, 4); + string name = (const char *)sqlite3_column_text(psqlsmt, 1); + string tag = (const char *)sqlite3_column_text(psqlsmt, 2); + error::printInfo("Client_ID: " + std::to_string(client_id)); + error::printInfo("Passwd: " + std::to_string(passwd)); + error::printInfo("Name: " + name); + error::printInfo("Tag: " + tag); + + } + else { + error::printError("[NONE INFO]"); + } + sqlite3_finalize(psqlsmt); + } else if (cmdstr == "quit") { //关闭所有打开的文件描述符 diff --git a/src/model.cpp b/src/model.cpp index db170e6..4547f2d 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -51,6 +51,27 @@ void getSQEPublicKey(respond *pres,void *args){ else if_wait = -1; } +void loginSQECallback(respond *pres, void *args) { + if (pres != nullptr) { + string resjson = string(pres->buff, pres->buff_size); + Document resdoc; + resdoc.Parse(resjson.data()); + string status = resdoc["status"].GetString(); + if (status == "ok") { + error::printSuccess("login succeed."); + if_wait = 0; + } + else { + error::printError("login failed."); + if_wait = -1; + } + } + else { + if_wait = -1; + printf("Request timeout.\n"); + } +} + void registerSQECallback(respond *pres,void *args){ if(pres != nullptr){ string resjson = string(pres->buff,pres->buff_size); @@ -58,6 +79,32 @@ void registerSQECallback(respond *pres,void *args){ resdoc.Parse(resjson.data()); string status = resdoc["status"].GetString(); if(status == "ok"){ + sqlite3 *psql = (sqlite3 *)args; + try { + //创建客户端描述信息数据表 + sql::table_create(psql, "client_register_info", { + {"client_id","INT"}, + {"name","TEXT"}, + {"tag","TEXT"}, + {"key","NONE"}, + {"passwd","INT"}, + {"status","INT"}, + }); + } + catch (const char *errstr) { + string errinfo = errstr; + if (errinfo == "fail to create table") { + error::printInfo("Table is already created."); + + sqlite3_stmt *psqlsmt; + const char *pzTail; + string sql_quote = "delete from client_register_info;"; + + sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); + sqlite3_step(psqlsmt); + sqlite3_finalize(psqlsmt); + } + } if_wait = 0; } else{ @@ -172,7 +219,25 @@ void *connectionDeamon(void *args){ pncryp->SelfParse(); printf("Register Status: "); if(pncryp->edoc["status"].GetString() == string("ok")){ - error::printSuccess("Succeed"); + uint64_t client_id = pncryp->edoc["client_id"].GetInt64(); + uint64_t passwd = pncryp->edoc["passwd"].GetInt64(); + sqlite3_stmt *psqlsmt; + const char *pzTail; + string sql_quote = "update client_register_info set client_id = ?1,passwd = ?2,status = 1 where rowid = 1;"; + sqlite3_prepare(pcntl->psql, sql_quote.data(), -1, &psqlsmt, &pzTail); + sqlite3_bind_int64(psqlsmt, 1, client_id); + sqlite3_bind_int64(psqlsmt, 2, passwd); + if (sqlite3_step(psqlsmt) == SQLITE_OK) { + error::printSuccess("Succeed"); + } + else { + error::printRed("Failed"); + sql::printError(pcntl->psql); + } + sqlite3_finalize(psqlsmt); + + + error::printInfo("\nStart Command Line Tools...\n"); //进入客户端管理终端 memcpy(pcntl->father_buff,"D_OK", sizeof(uint32_t)); @@ -222,6 +287,10 @@ void *clientServiceDeamon(void *arg) { connection_listener *pncl = new connection_listener(); pncl->client_addr = pclst->client_addr; pncl->data_sfd = pclst->server_cnt->GetDataSFD(); + //设置超时 + struct timeval timeout = { 3,0 }; + setsockopt(pncl->data_sfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)); + pncl->key = pclst->key; pncl->father_buff = pclst->father_buff; pncl->pif_atv = &pclst->if_active; @@ -229,6 +298,7 @@ void *clientServiceDeamon(void *arg) { pncl->beat_pid = pclst->beat_pid; pncl->listen_pid = pclst->listen_pid; pncl->send_pid = pclst->send_pid; + pncl->psql = pclst->psql; pthread_attr_t attr; pthread_attr_init(&attr); diff --git a/src/server.cpp b/src/server.cpp index 6da6d5e..78be55a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1330,17 +1330,14 @@ void *clientWaitDeamon(void *pvclt){ printf("Get Register: %s[%s]\n",pclr->name.data(),pclr->tag.data()); // 注册信息报文 - string res_type = "{\"status\":\"ok\",\"passwd\":null}"; + string res_type = "{\"status\":\"ok\",\"passwd\":null,\"client_id\":null}"; encrypt_post *ncryp = new encrypt_post(); ncryp->Parse(res_type); - uint8_t *ppidx = (uint8_t *)&pclr->passwd; - ncryp->edoc["passwd"].SetArray(); - Document::AllocatorType &allocator = ncryp->edoc.GetAllocator(); - for(int i = 0; i < 8; i++){ - ncryp->edoc["passwd"].PushBack(ppidx[i], allocator); - } + ncryp->edoc["client_id"].SetInt64(pclr->client_id); + ncryp->edoc["passwd"].SetInt64(pclr->passwd); + string send_data; ncryp->GetJSON(send_data);