添加与修改

This commit is contained in:
Saturneric 2019-03-04 18:40:45 +08:00
parent 1b81ea3839
commit 0708152757
6 changed files with 472 additions and 141 deletions

View File

@ -171,6 +171,7 @@ public:
ssize_t RecvRAW(char **p_rdt, Addr &taddr);
ssize_t RecvRAW_SM(char **p_rdt, Addr &taddr);
void SendRespond(string &str);
};
//TCP客户端套接字类

View File

@ -115,7 +115,7 @@ public:
uint32_t info;
// 信息串
char *msg = NULL;
unsigned long msg_size = 0;
unsigned long msg_size = 0;
// 来源ip地址
struct sockaddr_in address;
// 用简单字符串直接出适合
@ -214,6 +214,7 @@ struct client_register{
Addr t_addr;
// 守护线程ID
pthread_t tid;
sqlite3 *psql;
};
struct client_listen{
@ -225,6 +226,12 @@ struct client_listen{
client_register *pcltr;
};
struct connection_info {
bool if_listen = false;
bool if_beat = false;
bool if_send = false;
};
struct connection_listener{
int data_sfd;
Addr client_addr;
@ -234,6 +241,9 @@ struct connection_listener{
SocketTCPCServer *server_cnt = nullptr;
bool if_active = true;
bool *pif_atv = nullptr;
void *write_buff = nullptr;
struct connection_info *p_ci = nullptr;
pthread_t *beat_pid = nullptr, *listen_pid = nullptr, *send_pid = nullptr;
};
//通用服务器类
@ -338,7 +348,7 @@ public:
static void Post2Packet(packet &pkt, encrypt_post &pst, aes_key256 &key);
static void Packet2Post(packet &pkt, encrypt_post &pst, aes_key256 &key);
static void GetPostInfo(packet &pkt, encrypt_post &pst);
static void SendConnectionInfo(SocketTCPClient *pcnt_sock, bool ifshort);
static void SendConnectionInfo(SocketTCPClient *pcnt_sock, string type);
};
//通用客户端类

View File

@ -303,6 +303,7 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
int server(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &targets){
initClock();
setThreadsClock();
signal(SIGPIPE, SIG_IGN);
if(targets.size() == 0){
//Server nsvr;
//setServerClock(&nsvr, 3);
@ -468,55 +469,72 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
nclt.SetPublicKey(*ppbc);
sqlite3_finalize(psqlsmt);
aes_key256 naeskey;
nclt.SetAESKey(naeskey);
string reqstr = " {\"key\":null, \"name\":null, \"tag\":null, \"sqe_key\":null, \"listen_port\": null,\"listen_ip\":null}";
Document reqdata;
if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
// 生成并传递端对端加密报文密钥
reqdata["key"].SetArray();
Value &tmp_key = reqdata["key"];
const uint8_t *p_key = naeskey.GetKey();
Document::AllocatorType& allocator = reqdata.GetAllocator();
for (int idx = 0; idx <32; idx++) {
tmp_key.PushBack(p_key[idx],allocator);
}
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.tag.size());
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
//设置TCP监听端口
reqdata["listen_port"].SetInt(9052);
//如果强制指定客户端IP地址
string ip;
if(if_setip) ip = set_ip;
else ip = "127.0.0.1";
reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size());
//检测本地的注册信息
sql_quote = "select count(name) from sqlite_master where name = \"client_register_info\"";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
if (sqlite3_step(psqlsmt) != SQLITE_ROW) {
sql::printError(psql);
throw "database is abnormal";
}
int if_find = sqlite3_column_int(psqlsmt, 0);
if (if_find) {
//如果本地已经有注册信息
//构造请求
StringBuffer strbuff;
Writer<StringBuffer> writer(strbuff);
reqdata.Accept(writer);
string json_str = strbuff.GetString();
}
else {
//如果本地没有注册信息
//向主广场服务器注册
aes_key256 naeskey;
nclt.SetAESKey(naeskey);
printf("Connecting...\n");
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
nclt.NewRequestListener(preq, 44, psql,registerSQECallback);
string reqstr = " {\"key\":null, \"name\":null, \"tag\":null, \"sqe_key\":null, \"listen_port\": null,\"listen_ip\":null}";
//等待主广场服务器回应
if_wait = 1;
while (if_wait == 1) {
sleep(1);
}
Document reqdata;
if (reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
// 生成并传递端对端加密报文密钥
reqdata["key"].SetArray();
Value &tmp_key = reqdata["key"];
const uint8_t *p_key = naeskey.GetKey();
Document::AllocatorType& allocator = reqdata.GetAllocator();
for (int idx = 0; idx < 32; idx++) {
tmp_key.PushBack(p_key[idx], allocator);
}
reqdata["name"].SetString(nclt.name.data(), (uint32_t)nclt.name.size());
reqdata["tag"].SetString(nclt.tag.data(), (uint32_t)nclt.tag.size());
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
//设置TCP监听端口
reqdata["listen_port"].SetInt(9052);
//如果强制指定客户端IP地址
string ip;
if (if_setip) ip = set_ip;
else ip = "127.0.0.1";
reqdata["listen_ip"].SetString(ip.data(), (uint32_t)ip.size());
//构造请求
StringBuffer strbuff;
Writer<StringBuffer> writer(strbuff);
reqdata.Accept(writer);
string json_str = strbuff.GetString();
printf("Connecting...\n");
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
nclt.NewRequestListener(preq, 44, psql, registerSQECallback);
//等待主广场服务器回应
if_wait = 1;
while (if_wait == 1) {
sleep(1);
}
}
//得到服务器回应
if (!if_wait) {
// 成功注册
@ -540,23 +558,45 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
}
//创建客户端连接管理线程
pthread_t beat_pid = 0, listen_pid = 0, send_pid = 0;
connection_listener *pncl = new connection_listener();
pncl->client_addr = nclt.server_cnt->GetClientAddr();
pncl->data_sfd = nclt.server_cnt->GetDataSFD();
pncl->key = nclt.post_key;
pncl->father_buff = buff;
pncl->server_cnt = nclt.server_cnt;
pncl->beat_pid = &beat_pid;
pncl->listen_pid = &listen_pid;
pncl->send_pid = &send_pid;
pncl->p_ci = new connection_info();
pthread_create(&pncl->pid, NULL, clientServiceDeamon, pncl);
memset(buff, 0, sizeof(uint32_t));
while (1) {
//获得连接状态
if (!memcmp(buff, "CIFO", sizeof(uint32_t))) {
memcpy(buff, "RCFO", sizeof(uint32_t));
memcpy(buff+sizeof(uint32_t), pncl->p_ci, sizeof(connection_info));
}
//检测父进程信号
if(!memcmp(buff, "Exit", sizeof(uint32_t))){
else if(!memcmp(buff, "Exit", sizeof(uint32_t))){
pncl->if_active = false;
pthread_join(pncl->pid, NULL);
//注销所有主要线程
if(pncl->p_ci->if_beat) pthread_cancel(beat_pid);
if (pncl->p_ci->if_listen) pthread_cancel(listen_pid);
if (pncl->p_ci->if_send) pthread_cancel(send_pid);
pthread_cancel(pncl->pid);
nclt.server_cnt->Close();
//关闭所有打开的文件描述符
int fd = 0;
int fd_limit = sysconf(_SC_OPEN_MAX);
while (fd < fd_limit) close(fd++);
free(pncl->p_ci);
delete pncl;
memcpy(buff, "SEXT", sizeof(uint32_t));
//断开共享内存连接
@ -578,21 +618,62 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
}
usleep(1000);
}
error::printSuccess("\nShell For Client: ");
error::printSuccess("\n-------------------------------\nShell For Client: \n-------------------------------\n");
string cmdstr;
char cmd[1024];
while (1) {
printf(">");
gets_s(cmd,1024);
cmdstr = cmd;
if(cmdstr == "Exit"){
if(cmdstr == "stop"){
error::printInfo("Start to stop service...");
memcpy(buff, "Exit", sizeof(uint32_t));
while (memcmp(buff, "SEXT", sizeof(uint32_t))) {
sleep(10000);
usleep(1000);
}
error::printInfo("Service stopped.");
}
else if(cmdstr == "status"){
memcpy(buff, "CIFO", sizeof(uint32_t));
while (memcmp(buff, "RCFO", sizeof(uint32_t))) {
usleep(1000);
}
connection_info n_ci;
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");
}
else if (cmdstr == "quit") {
//关闭所有打开的文件描述符
int fd = 0;
//nclt.server_cnt->Close();
int fd_limit = sysconf(_SC_OPEN_MAX);
while (fd < fd_limit) close(fd++);
shmdt(buff);
exit(0);
}
else if (cmdstr == "ping") {
if (memcmp(buff, "WAIT", sizeof(uint32_t))) {
raw_data nrwd;
SQEServer::BuildSmallRawData(nrwd, "PING");
memcpy(buff, "WAIT", sizeof(uint32_t));
memcpy(buff+sizeof(uint32_t), &nrwd.msg_size, sizeof(uint64_t));
memcpy(buff + 3 * sizeof(uint32_t), nrwd.msg, nrwd.msg_size);
memcpy(buff + 3 * sizeof(uint32_t) + nrwd.msg_size, "TADS", sizeof(uint32_t));
memcpy(buff, "SDAT", sizeof(uint32_t));
Server::freeRawdataServer(nrwd);
}
}
}
}

View File

@ -12,13 +12,13 @@ extern int if_wait;
namespace error {
void printError(string error_info){
printf("\033[31mError: %s\n\033[0m",error_info.data());
printf("\033[31mError: %s\033[0m\n",error_info.data());
}
void printWarning(string warning_info){
printf("\033[33mWarning: %s\n\033[0m",warning_info.data());
printf("\033[33mWarning: %s\033[0m\n",warning_info.data());
}
void printSuccess(string succes_info){
printf("\033[32m%s\n\033[0m",succes_info.data());
printf("\033[32m%s\033[0m\n",succes_info.data());
}
void printRed(string red_info) {
printf("\033[31m%s\n\033[0m", red_info.data());
@ -58,11 +58,10 @@ void registerSQECallback(respond *pres,void *args){
resdoc.Parse(resjson.data());
string status = resdoc["status"].GetString();
if(status == "ok"){
printf("Register succeed.\n");
if_wait = 0;
}
else{
printf("Register Fail.\n");
error::printError("register failed.");
if_wait = -1;
}
}
@ -83,7 +82,6 @@ void *connectionDeamon(void *args){
SocketTCPCServer ntcps;
ntcps.SetDataSFD(pcntl->data_sfd);
ntcps.SetClientAddr(pcntl->client_addr);
// 获得连接的类型是长链还是断链
size = ntcps.RecvRAW_SM(&buff, t_addr);
raw_data *pnrwd = new raw_data();
@ -94,22 +92,45 @@ void *connectionDeamon(void *args){
if(Server::CheckRawMsg(buff, size)){
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){
//接收长连接
if_sm = false;
}
else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){
//接收短连接
if_sm = true;
ntcps.SendRespond(dget);
}
else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){
if_sm = true;
//printf("Listen Connection From Server\n");
ntcps.CloseConnection();
pthread_exit(NULL);
//发送长连接
if_sm = false;
pcntl->p_ci->if_listen = true;
*pcntl->listen_pid = pcntl->pid;
pcntl->write_buff = pcntl->father_buff;
while (1) {
if (*pcntl->pif_atv == false) {
close(pcntl->data_sfd);
pcntl->p_ci->if_listen = false;
delete pcntl;
pthread_exit(NULL);
}
if (!memcmp(pcntl->write_buff, "SDAT", sizeof(uint32_t))) {
uint32_t nsrwd_size = 0;
Byte buff[BUFSIZ];
memcpy(&nsrwd_size, pcntl->write_buff + sizeof(uint32_t), sizeof(uint32_t));
if (!memcmp(pcntl->write_buff + 3 * sizeof(uint32_t) + nsrwd_size, "TADS", sizeof(uint32_t))) {
memcpy(buff, pcntl->write_buff + 3 * sizeof(uint32_t), nsrwd_size);
send(pcntl->data_sfd, buff, nsrwd_size, 0);
}
else error::printError("buffer error.");
memset(pcntl->write_buff, 0, sizeof(uint32_t));
}
usleep(1000);
}
}
else{
//断开无效连接
printf("Connection Illegal.\n");
printf("Connection Info Illegal.\n");
delete pnrwd;
close(pcntl->data_sfd);
delete pcntl;
@ -123,6 +144,7 @@ void *connectionDeamon(void *args){
delete pnrwd;
pthread_exit(NULL);
}
Server::freeRawdataServer(*pnrwd);
delete pnrwd;
while (1) {
@ -134,7 +156,6 @@ void *connectionDeamon(void *args){
//区分长连接与短连接
if(if_sm) size = ntcps.RecvRAW(&buff, t_addr);
else size = ntcps.RecvRAW_SM(&buff, t_addr);
if(size > 0){
raw_data *pnrwd = new raw_data();
packet *nppkt = new packet();
@ -149,8 +170,10 @@ void *connectionDeamon(void *args){
if(!memcmp(&pncryp->type, "JRES", sizeof(uint32_t))){
//自我解析
pncryp->SelfParse();
printf("Register Status: ");
if(pncryp->edoc["status"].GetString() == string("ok")){
error::printSuccess("Register Successful.");
error::printSuccess("Succeed");
error::printInfo("\nStart Command Line Tools...\n");
//进入客户端管理终端
memcpy(pcntl->father_buff,"D_OK", sizeof(uint32_t));
}
@ -163,19 +186,16 @@ void *connectionDeamon(void *args){
}
//心跳连接
else if(!memcmp(&pnrwd->info, "BEAT", sizeof(uint32_t))){
//printf("Connection Beated.\n");
if (!pcntl->p_ci->if_beat) {
pcntl->p_ci->if_beat = true;
*pcntl->beat_pid = pcntl->pid;
}
}
Server::freeRawdataServer(*pnrwd);
Server::freePcaketServer(*nppkt);
}
else if(size < 0){
//printf("Lost Connection From Server.\n");
delete pnrwd;
delete pncryp;
delete nppkt;
delete pcntl;
break;
}
free(buff);
delete pnrwd;
delete pncryp;
@ -190,18 +210,25 @@ void *connectionDeamon(void *args){
void *clientServiceDeamon(void *arg) {
connection_listener *pclst = (connection_listener *)arg;
while (1) {
if (pclst->if_active == false) {
break;
}
//接受新连接
pclst->server_cnt->Accept();
//构造连接守护子进程
//构造连接守护子线程
connection_listener *pncl = new connection_listener();
pncl->client_addr = pclst->client_addr;
pncl->data_sfd = pclst->server_cnt->GetDataSFD();
pncl->key = pclst->key;
pncl->father_buff = pclst->father_buff;
pncl->pif_atv = &pclst->if_active;
pncl->p_ci = pclst->p_ci;
pncl->beat_pid = pclst->beat_pid;
pncl->listen_pid = pclst->listen_pid;
pncl->send_pid = pclst->send_pid;
pthread_attr_t attr;
pthread_attr_init(&attr);

View File

@ -667,6 +667,28 @@ SQEServer::SQEServer(int port):Server(port){
error::printSuccess("Server Name: "+name);
error::printSuccess("Listen Port: " + std::to_string(port));
sql_quote = "select count(name) from sqlite_master where name = \"register_info\"";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
if (sqlite3_step(psqlsmt) != SQLITE_ROW) {
sql::printError(psql);
throw "database is abnormal";
}
int if_find = sqlite3_column_int(psqlsmt,0);
if (!if_find) {
sql::table_create(psql, "register_info", {
{"name","TEXT"},
{"tag","TEXT"},
{"client_id","INT"},
{"key","NONE"},
{"ip","TEXT"},
{"udp_port","INT"},
{"tcp_port","INT"},
{"passwd","INT"},
{"status","INT"}
});
error::printInfo("create table register_info.");
}
sqlite3_finalize(psqlsmt);
}
void SQEServer::Packet2Request(packet &pkt, request &req){
@ -749,8 +771,9 @@ void SQEServer::ProcessRequset(void){
pclr->t_addr.SetIP(jdoc["listen_ip"].GetString());
pclr->t_addr.SetPort(port);
pclr->passwd = rand64();
pclr->psql = psql;
// 联络线程生命周期
pclr->click = 9999;
pclr->click = 99999;
//if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
client_lst.insert({pclr->client_id,pclr});
//pthread_mutex_unlock(&mutex_cltreg);
@ -766,7 +789,33 @@ void SQEServer::ProcessRequset(void){
pncr->arg = (void *)pclr;
newClock(pncr);
rids.insert({preq->r_id,pclr});
//写入注册信息到数据库
sqlite3_stmt *psqlsmt;
sql::insert_info(psql, &psqlsmt, "register_info",{
{"name","?1"},
{"tag","?2"},
{"client_id","?3"},
{"key","?4"},
{"ip","?5"},
{"passwd","?6"},
{"tcp_port","?7"},
{"udp_port","?8"},
{"status","?9"}
});
sqlite3_bind_text(psqlsmt, 1, pclr->name.data(), -1, SQLITE_TRANSIENT);
sqlite3_bind_text(psqlsmt, 2, pclr->tag.data(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int64(psqlsmt, 3, pclr->client_id);
sqlite3_bind_blob(psqlsmt, 4, (const void *)pclr->key.key, sizeof(uint64_t) * 4, SQLITE_TRANSIENT);
sqlite3_bind_text(psqlsmt, 5, jdoc["listen_ip"].GetString(), -1, SQLITE_TRANSIENT);
sqlite3_bind_int64(psqlsmt, 6, pclr->passwd);
sqlite3_bind_int(psqlsmt, 7, port);
sqlite3_bind_int(psqlsmt, 8, preq->recv_port);
sqlite3_bind_int(psqlsmt, 9, 0);
sqlite3_step(psqlsmt);
sqlite3_finalize(psqlsmt);
}
// 构建回复包
respond *pnr = new respond();
@ -787,6 +836,84 @@ void SQEServer::ProcessRequset(void){
pthread_mutex_unlock(&mutex_sndpkt);
}
else if(preq->type == "client login"){
preq->req_doc.Parse(preq->data.data());
Document &ldoc = preq->req_doc;
sqlite3_stmt *psqlsmt;
const char *pzTail;
client_register *pclr = new client_register();
pclr->client_id = ldoc["client_id"].GetInt64();
string sql_quote = "select * from register_info where client_id = ?1;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
sqlite3_bind_text(psqlsmt, 1, std::to_string(pclr->client_id).data(), -1, SQLITE_TRANSIENT);
if (sqlite3_step(psqlsmt) == SQLITE_DONE) {
error::printInfo("Invaild login.");
delete pclr;
sqlite3_finalize(psqlsmt);
}
else {
pclr->passwd = sqlite3_column_int64(psqlsmt, 7);
if (pclr->passwd == ldoc["passwd"].GetInt64()) {
if (sqlite3_column_int(psqlsmt, 8) == 0) {
//完善客户端登录管理结构体
pclr->name = (const char *)sqlite3_column_text(psqlsmt, 0);
pclr->tag = (const char *)sqlite3_column_text(psqlsmt, 1);
pclr->t_addr.SetIP((const char *)sqlite3_column_text(psqlsmt, 4));
pclr->t_addr.SetPort(sqlite3_column_int(psqlsmt, 6));
pclr->psql = psql;
memcpy((void *)pclr->key.GetKey(), sqlite3_column_blob(psqlsmt, 3), sizeof(uint64_t) * 4);
printf("Login successfully %s[%s]:%s\n", pclr->name.data(), pclr->tag.data());
//注册客户端联络守护进程
clock_register *pncr = new clock_register();
pncr->if_thread = true;
pncr->if_reset = false;
pncr->click = 64;
pncr->rawclick = 0;
pncr->func = clientWaitDeamon;
pncr->arg = (void *)pclr;
newClock(pncr);
rids.insert({ preq->r_id,pclr });
sqlite3_finalize(psqlsmt);
sql_quote = "update register_info set status = 1 where client_id = ?1";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
sqlite3_bind_int64(psqlsmt, 1, pclr->client_id);
sqlite3_step(psqlsmt);
sqlite3_finalize(psqlsmt);
}
else {
sqlite3_finalize(psqlsmt);
delete pclr;
}
//构建回复包
respond *pnr = new respond();
pnr->r_id = preq->r_id;
string res_data = "{\"status\":\"ok\"}";
pnr->SetBuff((Byte *)res_data.data(), (uint32_t)res_data.size());
pnr->type = "register respond";
pnr->t_addr = preq->t_addr;
pnr->t_addr.SetPort(preq->recv_port);
packet *pnpkt = new packet();
Respond2Packet(*pnpkt, *pnr);
delete pnr;
//将标准数据包添加到发送列表
if (pthread_mutex_lock(&mutex_sndpkt) != 0) throw "lock error";
packets_out.push_back(pnpkt);
pthread_mutex_unlock(&mutex_sndpkt);
}
else {
error::printInfo("Wrong password");
delete pclr;
sqlite3_finalize(psqlsmt);
}
}
}
delete preq;
preq = nullptr;
}
@ -1062,7 +1189,7 @@ void *clientChecker(void *args){
break;
}
else{
sleep(3);
sleep(1);
}
}
pthread_exit(NULL);
@ -1076,54 +1203,61 @@ void encrypt_post::SelfParse(void) {
void *clientListener(void *args){
client_listen *pcltl = (client_listen *)args;
char *buff;
Addr taddr;
while(1){
// 如果连接断开
if(pcltl->if_connected == false) break;
Addr taddr;
// 建立新的监听连接
try {
pcltl->ptcps->Reconnect();
try {
pcltl->ptcps->Reconnect();
}
catch (const char *errinfo) {
string errstr = errinfo;
if (errstr == "fail to connect") {
pcltl->if_connected = false;
pthread_exit(NULL);
}
catch (const char *errinfo) {
string errstr = errinfo;
if (errstr == "fail to connect") {
pcltl->if_connected = false;
break;
}
}
// 说明连接类型
raw_data nsrwd;
SQEServer::BuildSmallRawData(nsrwd, "CNTL");
pcltl->ptcps->SendRAW(nsrwd.msg, nsrwd.msg_size);
Server::freeRawdataServer(nsrwd);
ssize_t size = pcltl->ptcps->RecvRAW(&buff, taddr);
if(size > 0){
if(Server::CheckRawMsg(buff, size)){
raw_data nrwd;
Server::ProcessSignedRawMsg(buff, size, nrwd);
}
//发送连接属性信息
SQEServer::SendConnectionInfo(pcltl->ptcps, "CNTL");
while (1) {
// 如果连接断开
if (pcltl->if_connected == false) break;
ssize_t size = pcltl->ptcps->RecvRAW(&buff, taddr);
if (size > 0) {
if (Server::CheckRawMsg(buff, size)) {
raw_data nrwd;
Server::ProcessSignedRawMsg(buff, size, nrwd);
//如果二进制串中储存端对端加密报文
if(!memcmp(&nrwd.info,"ECYP",sizeof(uint32_t))){
if (!memcmp(&nrwd.info, "ECYP", sizeof(uint32_t))) {
encrypt_post necryp;
SQEServer::SignedRawData2Post(nrwd, necryp, pcltl->pcltr->key);
if(!memcmp(&necryp.type,"JIFO",sizeof(uint32_t))){
if (!memcmp(&necryp.type, "JIFO", sizeof(uint32_t))) {
necryp.SelfParse();
printf("Client %s[%s] Send Encrypt Post(JSON).\n",pcltl->pcltr->name.data(),pcltl->pcltr->tag.data());
uint64_t pwd = necryp.edoc["pwdmd5"].GetInt64();
if(pwd == pcltl->pcltr->passwd){
printf("Password Check Passed.\n");
}
else{
printf("Wrong Password.\n");
}
}
//necryp.FreeBuff();
}
Server::freeRawdataServer(nrwd);
}
free(buff);
}
}
printf("Client %s[%s] Send Encrypt Post(JSON).\n", pcltl->pcltr->name.data(), pcltl->pcltr->tag.data());
uint64_t pwd = necryp.edoc["pwdmd5"].GetInt64();
if (pwd == pcltl->pcltr->passwd) {
printf("Password Check Passed.\n");
}
else {
printf("Wrong Password.\n");
}
}
//necryp.FreeBuff();
}
else if (!memcmp(&nrwd.info, "PING", sizeof(uint32_t))) {
error::printInfo("client ping.");
}
Server::freeRawdataServer(nrwd);
}
free(buff);
}
else if(size < 0){
pcltl->if_connected == false;
break;
}
usleep(1000);
}
pthread_exit(NULL);
}
bool resFromClient(SocketTCPClient *pcnt_sock){
@ -1156,11 +1290,10 @@ void SQEServer::Post2SignedRawData(encrypt_post &ecyp, aes_key256 &key, raw_data
Server::SignedRawdata(&rw,"ECYP");
}
void SQEServer::SendConnectionInfo(SocketTCPClient *pcnt_sock, bool ifshort) {
void SQEServer::SendConnectionInfo(SocketTCPClient *pcnt_sock, string type) {
raw_data nsrwd;
//说明连接类型
if(ifshort) SQEServer::BuildSmallRawData(nsrwd, "SCNT");
else SQEServer::BuildSmallRawData(nsrwd, "LCNT");
SQEServer::BuildSmallRawData(nsrwd, type.data());
pcnt_sock->SendRAW(nsrwd.msg, nsrwd.msg_size);
Server::freeRawdataServer(nsrwd);
}
@ -1170,6 +1303,7 @@ void *clientWaitDeamon(void *pvclt){
client_register *pclr = (client_register *)pcti->args;
SocketTCPClient *pcnt_sock = nullptr;
bool if_success = false;
//尝试主动连接客户端
printf("Connecting client %s[%s].\n",pclr->name.data(),pclr->tag.data());
for(int i = 0; i < 8; i++){
if(tryConnection(&pcnt_sock, pclr)){
@ -1181,6 +1315,14 @@ void *clientWaitDeamon(void *pvclt){
}
if(!if_success){
printf("Fail To Get Register.\n");
//更新登录信息
string sql_quote = "update register_info set status = 0 where client_id = ?1";
sqlite3_stmt *psqlsmt;
const char *pzTail;
sqlite3_prepare(pclr->psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
sqlite3_bind_int64(psqlsmt, 1, pclr->client_id);
sqlite3_step(psqlsmt);
sqlite3_finalize(psqlsmt);
delete pclr;
clockThreadFinish(pcti->tid);
pthread_exit(NULL);
@ -1208,7 +1350,7 @@ void *clientWaitDeamon(void *pvclt){
SQEServer::Post2SignedRawData(*ncryp, pclr->key, *pnrwd);
//发送连接属性信息
SQEServer::SendConnectionInfo(pcnt_sock,true);
SQEServer::SendConnectionInfo(pcnt_sock,"SCNT");
//等待反馈
if (resFromClient(pcnt_sock)) {
pcnt_sock->SendRAW(pnrwd->msg, pnrwd->msg_size);
@ -1216,13 +1358,21 @@ void *clientWaitDeamon(void *pvclt){
}
else {
//注册连接未被识别
error::printError("Client connection error.");
error::printError("client connection error.");
delete pclr;
delete pnrwd;
delete ncryp;
clockThreadFinish(pcti->tid);
pthread_exit(NULL);
}
string sql_quote = "update register_info set status = 1 where client_id = ?1";
sqlite3_stmt *psqlsmt;
const char *pzTail;
sqlite3_prepare(pclr->psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
sqlite3_bind_int64(psqlsmt, 1, pclr->client_id);
sqlite3_step(psqlsmt);
sqlite3_finalize(psqlsmt);
//建立客户端连接管理信息提供结构
client_listen *pcltl = new client_listen();
@ -1243,6 +1393,15 @@ void *clientWaitDeamon(void *pvclt){
sleep(1);
if(pcltl->if_connected == false){
printf("Register lost %s[%s]\n",pclr->name.data(),pclr->tag.data());
//更新登录信息
string sql_quote = "update register_info set status = 0 where client_id = ?1";
sqlite3_stmt *psqlsmt;
const char *pzTail;
sqlite3_prepare(pclr->psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
sqlite3_bind_int64(psqlsmt, 1, pclr->client_id);
sqlite3_step(psqlsmt);
sqlite3_finalize(psqlsmt);
//服务端销户?
break;
}
}

View File

@ -120,12 +120,38 @@ ssize_t SocketUDPClient::SendRAW(char *buff, unsigned long size){
}
ssize_t SocketTCPClient::SendRAW(char *buff, unsigned long size){
ssize_t send_size = send(client_sfd, buff, size, 0);
/*if(send_size < 0){
printf("Error[%u]:",errno);
perror("send");
}*/
return send_size;
//对于长数据进行分段发送
if (size > 1023) {
ssize_t idx = 0, nidx = 0;
Byte vbuff[1024], gbuff[1024];
while (idx < size-1) {
if (!idx) memcpy(vbuff, "DSAT", sizeof(uint32_t));
else memcpy(vbuff, "DCST", sizeof(uint32_t));
if (idx + 1000 < size - 1) {
nidx = idx + 1000;
memcpy(vbuff + sizeof(uint32_t) + nidx - idx + 1, "DCTN", sizeof(uint32_t));
}
else {
nidx = size - 1;
memcpy(vbuff + sizeof(uint32_t) + nidx - idx + 1, "DFSH", sizeof(uint32_t));
}
memcpy(vbuff + sizeof(uint32_t), buff + idx, nidx - idx + 1);
send(client_sfd, vbuff, 2 * sizeof(uint32_t) + nidx - idx + 1, 0);
int grtn = recv(client_sfd, gbuff, BUFSIZ,0);
if (grtn > 0 && !memcmp(gbuff, "DGET", sizeof(uint32_t)));
else {
return -1;
}
idx = nidx + 1;
}
return size;
}
else {
ssize_t send_size = send(client_sfd, buff, size, 0);
return send_size;
}
}
void SocketClient::SetSendSockAddr(struct sockaddr_in tsi){
@ -136,15 +162,42 @@ void SocketTCPClient::Close(void){
close(client_sfd);
}
//长连接数据接收
ssize_t SocketTCPCServer::RecvRAW_SM(char **p_rdt, Addr &taddr){
ssize_t tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0);
if (tmp_bdtas > 0) {
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
}
return tmp_bdtas;
ssize_t bdtas = 0, tmp_bdtas;
*p_rdt = nullptr;
bool dsat = false, dfsh = false, if_signal = false;
while (!dfsh && (tmp_bdtas = recv(data_sfd, buff, BUFSIZ, 0)) > 0) {
if (!memcmp(buff, "NETC", sizeof(uint32_t))) {
dsat = true;
dfsh = true;
if_signal = true;
}
if (!memcmp(buff, "DSAT", sizeof(uint32_t))) dsat = true;
if (!memcmp(buff+tmp_bdtas-sizeof(uint32_t), "DFSH", sizeof(uint32_t))) dfsh = true;
if (dsat) {
send(data_sfd, "DGET", sizeof(uint32_t), 0);
if (*p_rdt == nullptr) {
if (if_signal) {
*p_rdt = (char *)malloc(tmp_bdtas);
memcpy(*p_rdt, buff, tmp_bdtas);
bdtas += tmp_bdtas;
continue;
}
*p_rdt = (char *)malloc(tmp_bdtas - 2 * sizeof(uint32_t));
memcpy(*p_rdt, buff + sizeof(uint32_t), tmp_bdtas - 2 * sizeof(uint32_t));
}
else {
*p_rdt = (char *)realloc(*p_rdt, bdtas + tmp_bdtas - 2 * sizeof(uint32_t));
memcpy(*p_rdt + bdtas, buff + sizeof(uint32_t), tmp_bdtas - 2 * sizeof(uint32_t));
}
}
bdtas += tmp_bdtas;
}
return bdtas;
}
//短连接数据接收
ssize_t SocketTCPCServer::RecvRAW(char **p_rdt, Addr &taddr){
ssize_t bdtas = 0 ,tmp_bdtas;
*p_rdt = nullptr;
@ -178,7 +231,7 @@ void SocketTCPCServer::CloseConnection(void){
close(data_sfd);
}
void SocketTCPCServer::Close(void) {
close(server_sfd);
shutdown(server_sfd, SHUT_RDWR);
}