diff --git a/include/instruct.h b/include/instruct.h index 1936d7d..6bb44a5 100644 --- a/include/instruct.h +++ b/include/instruct.h @@ -21,15 +21,6 @@ #include "rsa.h" #include "rng.hpp" - -//提示信息打印类函数 -namespace error{ - void printError(string error_info); - void printWarning(string warning_info); - void printSuccess(string succes_info); - void printRed(string red_info); -} - struct instructions{ int (*unpack)(string, vector &, vector &, vector &) = NULL; int (*construct)(string, vector &, vector &, vector &) = NULL; diff --git a/include/net.h b/include/net.h index ef1eace..e070722 100644 --- a/include/net.h +++ b/include/net.h @@ -55,6 +55,7 @@ public : // 临时缓冲区 char buff[BUFSIZ]; SocketServer(int port,bool ipv4){ + server_addr.SetIP("127.0.0.1"); server_addr.SetPort(port); if(ipv4){ ipptl = AF_INET; diff --git a/include/server.h b/include/server.h index 42e4bca..7b1e1ba 100644 --- a/include/server.h +++ b/include/server.h @@ -181,6 +181,8 @@ struct box_listener{ uint16_t cnt; // 接收到的分包数量 uint16_t nbn; + //分包来源地址 + sockaddr_in address; // 储存接收到的分包的动态数组 net_box **boxs; // 合并分包成RawData @@ -221,6 +223,7 @@ struct connection_listener{ Addr client_addr; aes_key256 key; pthread_t pid; + void *father_buff; }; //通用服务器类 @@ -307,6 +310,8 @@ protected: map client_lst; // 加密端对端报文 listpost_lst; + //服务器名 + string name; public: SQEServer(int port = 9048); void ProcessPacket(void); @@ -333,7 +338,7 @@ class Client{ // 回复处理列表 list res_lst; // 请求监听端口 - uint32_t listen_port; + uint16_t listen_port; SocketUDPServer socket; SocketUDPClient send_socket; // 与服务器建立的稳定链接 diff --git a/include/type.h b/include/type.h index f33b0ba..f5f9651 100644 --- a/include/type.h +++ b/include/type.h @@ -44,6 +44,7 @@ #include #include #include +#include using std::string; @@ -65,4 +66,13 @@ typedef unsigned char UByte; #define RESPOND_TYPE 101 #define ENCRYPT_POST_TYPE 102 +//提示信息打印类函数 +namespace error { + void printError(string error_info); + void printWarning(string warning_info); + void printSuccess(string succes_info); + void printRed(string red_info); + void printInfo(string info); +} + #endif /* type_h */ diff --git a/src/addr.cpp b/src/addr.cpp index c2d4d10..3faf168 100644 --- a/src/addr.cpp +++ b/src/addr.cpp @@ -14,10 +14,8 @@ Addr::Addr(string ip_addr, int port, bool ipv4){ address.sin_family = AF_INET; else address.sin_family = AF_INET6; - address.sin_port = htons(port); - in_addr_t ipu = inet_addr(ip_addr.data()); - memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t)); - + address.sin_port = htons((uint16_t)port); + address.sin_addr.s_addr = inet_addr(ip_addr.data()); addr_size = sizeof(address); } @@ -49,13 +47,12 @@ void Addr::SetSize(void){ } void Addr::SetPort(int port){ - address.sin_port = htons(port); + address.sin_port = htons((uint16_t)port); addr_size = sizeof(address); } void Addr::SetIP(string ip_addr){ - in_addr_t ipu = inet_addr(ip_addr.data()); - memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t)); + address.sin_addr.s_addr = inet_addr(ip_addr.data()); addr_size = sizeof(address); } diff --git a/src/aes.cpp b/src/aes.cpp index 0e25f6c..c55f53e 100755 --- a/src/aes.cpp +++ b/src/aes.cpp @@ -299,7 +299,7 @@ static void ShiftRows(state_t* state) static uint8_t xtime(uint8_t x) { - return ((x<<1) ^ (((x>>7) & 1) * 0x1b)); + return (uint8_t)((x<<1) ^ (((x>>7) & 1) * 0x1b)); } // MixColumns function mixes the columns of the state matrix @@ -558,7 +558,7 @@ void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length) ctx->Iv[bi] = 0; continue; } - ctx->Iv[bi] += (uint8_t) 1; + ctx->Iv[bi] += 1; break; } bi = 0; diff --git a/src/client.cpp b/src/client.cpp index 94a3d6b..8346dcb 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -46,7 +46,6 @@ void *clientRespondDeamon(void *pvclt){ if(tlen > 0){ // 记录有效数据包 if(Server::CheckRawMsg(str, tlen)){ - raw_data *ptrdt = new raw_data(); Server::ProcessSignedRawMsg(str, tlen, *ptrdt); ptrdt->address = *(struct sockaddr_in *)taddr.RawObj(); @@ -155,6 +154,7 @@ void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type *ppreq = pnreq; } +//创建新的对服务器的请求 void Client::NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *,void *)){ request_listener *pnrl = new request_listener(); packet npkt; @@ -164,17 +164,19 @@ void Client::NewRequestListener(request *preq, int timeout, void *args, void (*c pnrl->clicks = 0; pnrl->p_req = preq; pnrl->args = args; + SQEServer::Request2Packet(npkt, *preq); Server::Packet2Rawdata(npkt, pnrl->trwd); // 检查请求是否要求加密 if(preq->if_encrypt == true){ + Server::EncryptRSARawMsg(pnrl->trwd, sqe_pbc); Server::SignedRawdata(&pnrl->trwd,"RPKT"); } else{ Server::SignedRawdata(&pnrl->trwd,"SPKT"); } - + send_socket.SetSendSockAddr(*pnrl->p_req->t_addr.Obj()); SendRawData(&pnrl->trwd); req_lst.push_back(pnrl); diff --git a/src/controller.cpp b/src/controller.cpp index b137fd5..45b5801 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -215,14 +215,19 @@ int set(string instruct, vector &configs, vector &lconfigs, vect int if_find = sqlite3_column_int(psqlsmt, 0); if(if_find); else{ - error::printError("Couldn't SET before INIT process."); + error::printError("Couldn't SET before INIT."); return -1; } sqlite3_finalize(psqlsmt); + if(targets[0] == "server"){ + if (targets.size() < 3) { + error::printError("Illegal Args.\nFromat set server [server_ip] [server_port]."); + return -1; + } sql_quote = "UPDATE client_info SET msqes_ip = ?1, msqes_port = ?2 WHERE rowid = 1;"; sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); - + //检查广场服务器IP地址是否正确 if(!Addr::checkValidIP(targets[1])){ error::printError("Arg(ipaddr) is abnomal."); sqlite3_finalize(psqlsmt); @@ -230,7 +235,7 @@ int set(string instruct, vector &configs, vector &lconfigs, vect return -1; } sqlite3_bind_text(psqlsmt, 1, targets[1].data(), -1, SQLITE_TRANSIENT); - + //获得广场服务器端口 stringstream ss; ss< &configs, vector &lconfigs, vect return -1; } sqlite3_bind_int(psqlsmt, 2, port); + + //执行数据库指令 int rtn = sqlite3_step(psqlsmt); if(rtn != SQLITE_DONE){ sql::printError(psql); @@ -250,6 +257,11 @@ int set(string instruct, vector &configs, vector &lconfigs, vect sqlite3_finalize(psqlsmt); } else if (targets[0] == "key"){ + if (targets.size() < 3) { + error::printError("Illegal Args.\nFromat set key [key_type] [key]"); + return -1; + } + //客户端远程管理口令 if(targets[1] == "admin"){ string hexresult; SHA1_Easy(hexresult, targets[2]); @@ -264,6 +276,7 @@ int set(string instruct, vector &configs, vector &lconfigs, vect } sqlite3_finalize(psqlsmt); } + //广场服务器访问口令 else if(targets[1] == "server"){ sql_quote = "UPDATE client_info SET msqes_key = ?1 WHERE rowid = 1;"; sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); @@ -278,6 +291,10 @@ int set(string instruct, vector &configs, vector &lconfigs, vect return -1; } } + else { + error::printError("Operation doesn't make sense."); + return 0; + } error::printSuccess("Succeed."); sqlite3_close(psql); return 0; @@ -287,8 +304,10 @@ int server(string instruct, vector &configs, vector &lconfigs, v initClock(); setThreadsClock(); if(targets.size() == 0){ - Server nsvr; - setServerClock(&nsvr, 3); + //Server nsvr; + //setServerClock(&nsvr, 3); + SQEServer nsvr; + setServerClockForSquare(&nsvr, 3); } else{ if(targets[0] == "square"){ @@ -363,37 +382,45 @@ int construct(string instruct, vector &configs, vector &lconfigs } int client(string instruct, vector &configs, vector &lconfigs, vector &targets){ + sqlite3 *psql; sqlite3_stmt *psqlsmt; const char *pzTail; + if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){ sql::printError(psql); return -1; } + // 初始化时钟 initClock(); setThreadsClock(); // 建立客户端 Client nclt(9050); + bool if_setip = false; string set_ip; + if(config_search(configs, "-p")){ set_ip = targets[0]; printf("Set IP: %s\n",set_ip.data()); if_setip = true; } + setClientClock(&nclt, 3); + request *preq; + // 获得主广场服务器的通信公钥 string sql_quote = "select count(*) from client_info where rowid = 1 and msqes_rsa_public is null;"; sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); sqlite3_step(psqlsmt); int if_null = sqlite3_column_int(psqlsmt, 0); sqlite3_finalize(psqlsmt); - + // 获得主广场服务器的ip地址及其通信端口 string msqe_ip; int msqe_port; @@ -403,12 +430,17 @@ int client(string instruct, vector &configs, vector &lconfigs, v msqe_ip = (const char *)sqlite3_column_text(psqlsmt, 0); msqe_port = sqlite3_column_int(psqlsmt, 1); sqlite3_finalize(psqlsmt); - + error::printSuccess("Main Server IP: " + msqe_ip); + error::printSuccess("Main Server Port: " + std::to_string(msqe_port)); + // 如果本地没有主广场服务器的公钥 if(if_null){ + //向广场服务器申请通信公钥 nclt.NewRequest(&preq, msqe_ip, msqe_port, "public request", "request for public key"); nclt.NewRequestListener(preq, 30, psql, getSQEPublicKey); if_wait = 1; + + //等待广场服务器回应 while (if_wait == 1) { sleep(10); } @@ -416,15 +448,18 @@ int client(string instruct, vector &configs, vector &lconfigs, v #ifdef DEBUG printf("Succeed In Getting Rsa Public Key From SQEServer.\n"); #endif + error::printSuccess("Succeed In Requesting Public Key."); } else{ #ifdef DEBUG printf("Error In Getting Rsa Public Key From SQEServer.\n"); #endif + error::printError("Fail To Request Public Key."); throw "connection error"; return -1; } } + // 获得与广场服务器的通信的公钥 sql_quote = "select msqes_rsa_public from client_info where rowid = 1;"; sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); @@ -440,7 +475,8 @@ int client(string instruct, vector &configs, vector &lconfigs, v Document reqdata; if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json"; -// key + +// 生成并传递端对端加密报文密钥 reqdata["key"].SetArray(); Value &tmp_key = reqdata["key"]; const uint8_t *p_key = naeskey.GetKey(); @@ -448,61 +484,78 @@ int client(string instruct, vector &configs, vector &lconfigs, v 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.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()); - reqdata["listen_port"].SetInt(9053); - + //设置TCP监听端口 + reqdata["listen_port"].SetInt(9052); + + + //如果强制指定客户端IP地址 string ip; if(if_setip) ip = set_ip; - else ip = inet_ntoa(nclt.server_cnt->GetAddr().Obj()->sin_addr); - + else ip = "127.0.0.1"; + reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size()); - + + + //构造请求 StringBuffer strbuff; - Writer writer(strbuff); + Writer writer(strbuff); reqdata.Accept(writer); string json_str = strbuff.GetString(); - printf("JSON: %s\n",json_str.data()); + + printf("Connecting...\n"); // 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作 nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true); - nclt.NewRequestListener(preq, 99, psql,registerSQECallback); - + nclt.NewRequestListener(preq, 44, psql,registerSQECallback); + + //等待主广场服务器回应 if_wait = 1; - while (if_wait) { + while (if_wait == 1) { sleep(1); } if (!if_wait) { + // 成功注册 - printf("Wait for server to connect\n"); + printf("Get Respond From Server.\n"); // 创建守护进程 - 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."); - nclt.server_cnt = new SocketTCPCServer(9053); + nclt.server_cnt = new SocketTCPCServer(9052); nclt.server_cnt->Listen(); + // 获得共享内存地址 Byte *buff = (Byte *)shmat(shmid, NULL, 0); if(shmid == -1){ printf("SHMAT Failed.\n"); } + while (1) { - if(!memcmp(buff, "SEND", sizeof(uint32_t))){ - printf("Get Sending Raw Data\n"); - memset(buff, 0, sizeof(uint32_t)); + //检测父进程信号 + if(!memcmp(buff, "Exit", sizeof(uint32_t))){ + error::printInfo("get killing signal."); + //断开共享内存连接 + shmdt(buff); + exit(0); } + nclt.server_cnt->Accept(); - //printf("Get connection request from server.\n"); + 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; + pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); @@ -512,24 +565,35 @@ int client(string instruct, vector &configs, vector &lconfigs, v } } else{ -// 父进程 + //父进程 + //创建并获得共享内存地址 int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT); Byte *buff = (Byte *)shmat(shmid, 0, 0); - printf("Net Command line: \n"); + while (1) { + if (!memcmp(buff, "D_OK", sizeof(uint32_t))) { + memset(buff, 0, sizeof(uint32_t)); + break; + } + usleep(1000); + } + error::printSuccess("\nShell For Client: "); while (1) { char cmd[1024]; printf(">"); - scanf("%s", cmd); + fgets(cmd,1024,stdin); string cmdstr = cmd; - if(cmdstr == "send"){ - memcpy(buff, "SEND", sizeof(uint32_t)); + if(cmdstr == "Exit"){ + memcpy(buff, "Exit", sizeof(uint32_t)); } } } + + } + return 0; } diff --git a/src/model.cpp b/src/model.cpp index 0b777aa..c765220 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -23,6 +23,9 @@ namespace error { void printRed(string red_info) { printf("\033[31m%s\n\033[0m", red_info.data()); } + void printInfo(string info) { + printf("%s\n", info.data()); + } } bool config_search(vector &configs,string tfg){ @@ -88,11 +91,11 @@ void *connectionDeamon(void *args){ Server::ProcessSignedRawMsg(buff, size, *pnrwd); if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){ if_sm = false; - printf("Long Connection From Server\n"); + printf("Long Connection From Server.\n"); } else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){ if_sm = true; - printf("Short Connection From Server\n"); + printf("Short Connection From Server.\n"); } else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){ if_sm = true; @@ -102,14 +105,14 @@ void *connectionDeamon(void *args){ pthread_exit(NULL); } else{ - printf("Connection illegal\n"); + printf("Connection illegal.\n"); delete pnrwd; pthread_exit(NULL); } } else{ - printf("Connection illegal\n"); + printf("Connection illegal.\n"); delete pnrwd; pthread_exit(NULL); } @@ -132,7 +135,8 @@ void *connectionDeamon(void *args){ Document ndoc; ndoc.Parse(jres_str.data()); if(ndoc["status"].GetString() == string("ok")){ - printf("Register Successful.\n"); + error::printSuccess("Register Successful."); + memcpy(pcntl->father_buff,"D_OK", sizeof(uint32_t)); } } } diff --git a/src/rsa.cpp b/src/rsa.cpp index b00ce4f..5abe818 100755 --- a/src/rsa.cpp +++ b/src/rsa.cpp @@ -38,7 +38,7 @@ long long ExtEuclid(long long a, long long b) return y; } -long long rsa_modExp(long long b, long long e, long long m) +long long rsa_modExp(unsigned long long b, unsigned long long e, unsigned long long m) { if (b < 0 || e < 0 || m <= 0){ exit(1); @@ -164,8 +164,7 @@ unsigned char *rsa_decrypt(const uint64_t *message, const unsigned long message_ unsigned char *decrypted = (unsigned char *) malloc(message_size/sizeof(uint64_t)); unsigned char *temp = (unsigned char *) malloc(message_size); if((decrypted == NULL) || (temp == NULL)){ - fprintf(stderr, - "Error: Heap allocation failed.\n"); + fprintf(stderr,"Error: Heap allocation failed.\n"); return NULL; } // Now we go through each 8-byte chunk and decrypt it. diff --git a/src/server.cpp b/src/server.cpp index 27873c6..d2fa265 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -79,6 +79,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){ setServerClock(psvr, clicks); pthread_mutex_init(&mutex_pktreq, NULL); pthread_mutex_init(&mutex_cltreg, NULL); + // 注册标准数据包处理守护时钟 clock_register *pncr = new clock_register(); pncr->if_thread = true; @@ -98,6 +99,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){ pncr->func = requestProcessorDeamonForSquare; pncr->arg = (void *)psvr; newClock(pncr); + error::printSuccess("Server Started..."); } Server::Server(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){ @@ -289,6 +291,7 @@ void Client::SendRawData(raw_data *trdt){ int Server::SentRawdata(struct raw_data *trdt){ // 对大包进行拆分发送 + int rtn = 0; if(trdt->msg_size > 256){ uint64_t aidx = 0,bidx = 0; int64_t alls = trdt->msg_size; @@ -306,13 +309,15 @@ int Server::SentRawdata(struct raw_data *trdt){ nnb.set(f_byte,bidx-aidx+1); nnb.build(); - send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size); + rtn = send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size); aidx = bidx+1; tmp_idx++; } } - else send_socket.SendRAW(trdt->msg, trdt->msg_size); - return 0; + else { + rtn = send_socket.SendRAW(trdt->msg, trdt->msg_size); + } + return rtn; } void net_box::FreeNetBox(void){ @@ -397,6 +402,7 @@ void *serverDeamon(void *pvcti){ if((pnbxl_itr = psvr->boxls.find(pnbx->b_id)) != psvr->boxls.end()){ box_listener *pnbxl = pnbxl_itr->second; + if (pthread_mutex_lock(&mutex_box) != 0) throw "lock error"; if(pnbxl->boxs[pnbx->idx] == nullptr && pnbxl->nbn < pnbxl->cnt){ pnbxl->boxs[pnbx->idx] = pnbx; @@ -412,6 +418,7 @@ void *serverDeamon(void *pvcti){ else{ box_listener *pnbxl = new box_listener(); pnbxl->cnt = pnbx->cnt; + pnbxl->address = *(struct sockaddr_in *)taddr.RawObj(); pnbxl->boxs = (net_box **) malloc(sizeof(net_box *) * pnbxl->cnt); memset(pnbxl->boxs, 0, sizeof(net_box *) * pnbxl->cnt); pnbxl->boxs[pnbx->idx] = pnbx; @@ -465,6 +472,7 @@ void *boxProcessorDeamon(void *pvcti){ raw_data *pnrdt = new raw_data(); pboxl->TogtRawData(*pnrdt); pnrdt->r_id = pboxl->b_id; + pnrdt->address = pboxl->address; psvr->rawdata_in.push_back(pnrdt); pboxl->clicks = -1; pboxl->free_boxs(); @@ -632,14 +640,16 @@ void SQEServer::ProcessPacket(void){ } SQEServer::SQEServer(int port):Server(port){ + //连接数据库 if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){ sql::printError(psql); throw "database is abnormal"; } + sqlite3_stmt *psqlsmt; const char *pzTail; -// 从数据库获得服务器的公私钥 - string sql_quote = "select sqes_public,sqes_private from server_info where rowid = 1;"; +// 从数据库获得服务器的公私钥及服务器名 + string sql_quote = "select sqes_public,sqes_private,name from server_info where rowid = 1;"; sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail); if(sqlite3_step(psqlsmt) != SQLITE_ROW){ sql::printError(psql); @@ -650,8 +660,13 @@ SQEServer::SQEServer(int port):Server(port){ tbyt = (Byte *)sqlite3_column_blob(psqlsmt, 1); memcpy(&prc, tbyt, sizeof(private_key_class)); - - sqlite3_finalize(psqlsmt); + name = (const char *)sqlite3_column_blob(psqlsmt, 2); + sqlite3_finalize(psqlsmt); + + //打印关键信息 + error::printSuccess("Server Name: "+name); + error::printSuccess("Listen Port: " + std::to_string(port)); + } void SQEServer::Packet2Request(packet &pkt, request &req){ @@ -734,13 +749,13 @@ void SQEServer::ProcessRequset(void){ pclr->t_addr.SetIP(jdoc["listen_ip"].GetString()); pclr->t_addr.SetPort(port); pclr->passwd = rand64(); -// 联络进程生命周期 +// 联络线程生命周期 pclr->click = 9999; //if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error"; client_lst.insert({pclr->client_id,pclr}); //pthread_mutex_unlock(&mutex_cltreg); - printf("Ready to connect client %s[%s].\n",pclr->name.data(),pclr->tag.data()); + printf("Register: %s[%s] IP: %s TCP_Port: %d\n",pclr->name.data(),pclr->tag.data(),jdoc["listen_ip"].GetString(),port); // 注册客户端联络守护进程 clock_register *pncr = new clock_register(); pncr->if_thread = true; @@ -827,7 +842,10 @@ void Server::ProcessSendPackets(void){ Packet2Rawdata(*ppkt, nrwd); SignedRawdata(&nrwd, "SPKT"); send_socket.SetSendSockAddr(ppkt->address); - SentRawdata(&nrwd); + if (SentRawdata(&nrwd) < 0) { + error::printError("fail to send package."); + perror("sendto"); + } freeRawdataServer(nrwd); freePcaketServer(*ppkt); delete ppkt;